The integer cases are easy. The double case is trickier, until you remember about infinities.
Note: If you consider the double constants "part of the api", you can replace them with overflowing expressions like 1E308 * 2
.
int sign(int i) {
if (i == 0) return 0;
if (i >> 31 != 0) return -1;
return +1;
}
int sign(long i) {
if (i == 0) return 0;
if (i >> 63 != 0) return -1;
return +1;
}
int sign(double f) {
if (f != f) throw new IllegalArgumentException("NaN");
if (f == 0) return 0;
f *= Double.POSITIVE_INFINITY;
if (f == Double.POSITIVE_INFINITY) return +1;
if (f == Double.NEGATIVE_INFINITY) return -1;
//this should never be reached, but I've been wrong before...
throw new IllegalArgumentException("Unfathomed double");
}
The following is a terrible approach that would get you fired at any job...
It depends on you getting a Stack Overflow Exception [or whatever Java calls it]... And it would only work for positive numbers that don't deviate from 0 like crazy.
Negative numbers are fine, since you would overflow to positive, and then get a stack overflow exception eventually [which would return false, or "yes, it is negative"]
Boolean isPositive<T>(T a)
{
if(a == 0) return true;
else
{
try
{
return isPositive(a-1);
}catch(StackOverflowException e)
{
return false; //It went way down there and eventually went kaboom
}
}
}
This will only works for everything except [0..2]
boolean isPositive = (n % (n - 1)) * n == n;
You can make a better solution like this (works except for [0..1])
boolean isPositive = ((n % (n - 0.5)) * n) / 0.5 == n;
You can get better precision by changing the 0.5 part with something like 2^m (m integer):
boolean isPositive = ((n % (n - 0.03125)) * n) / 0.03125 == n;
You can do something like this:
((long) (num * 1E308 * 1E308) >> 63) == 0 ? "+ve" : "-ve"
The main idea here is that we cast to a long and check the value of the most significant bit. As a double/float between -1 and 0 will round to zero when cast to a long, we multiply by large doubles so that a negative float/double will be less than -1. Two multiplications are required because of the existence of subnormals (it doesn't really need to be that big though).
What about this?
return ((num + "").charAt(0) == '-');
// Returns 0 if positive, nonzero if negative
public long sign(long value) {
return value & 0x8000000000000000L;
}
Call like:
long val1 = ...;
double val2 = ...;
float val3 = ...;
int val4 = ...;
sign((long) valN);
Casting from double / float / integer to long should preserve the sign, if not the actual value...
You say
we should not use conditional operators
But this is a trick requirement, because ==
is also a conditional operator. There is also one built into ? :
, while
, and for
loops. So nearly everyone has failed to provide an answer meeting all the requirements.
The only way to build a solution without a conditional operator is to use lookup table vs one of a few other people's solutions that can be boiled down to 0/1 or a character, before a conditional is met.
Here are the answers that I think might work vs a lookup table:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With