Reputation: 23
I'm not sure how to check if a double is a power of 2. This is my code so far:
double x = Double.longBitsToDouble(
Double.doubleToRawLongBits(n) & Double.doubleToRawLongBits(n - 1)
);
I used the following formula to find if the number is a power of 2:
n & (n - 1) == 0
But its not working.
Upvotes: 1
Views: 238
Reputation: 101
This should work for all cases, though whether infinity is considered a power of 2 may be application specific.
public static boolean isPowerOfTwo(double val) {
if (val <= 0.0 || Double.isNaN(val))
return false; // You can't raise 2 to a power and get a negative number or zero.
if (Double.isInfinite(val))
return false; // Arguable assumption. val is bigger than MAX_VALUE but we don't really know if it's a power of 2 or not.
long significand = Double.doubleToLongBits(val) & 0x000f_ffff_ffff_ffffL;
if (val >= Double.MIN_NORMAL)
return significand==0; // only the hidden 1 remains
else
return (Long.bitCount(significand) == 1); // denormalized, no hidden one, power of two only if exactly one bit in significand is set
}
Upvotes: 1
Reputation: 25855
If the problem is working with very large numbers, then Oleksandr's answer is better, but if you really want to check whether a double
is an even power of two, you can just check if the mantissa is zero:
(Double.doubleToLongBits(n) & 0x000fffffffffffffL) == 0
To be more robust, you'll want to handle the edge cases for non-normalized numbers (infinities, NaNs, denormals, and perhaps decide on whether zeroes should return true), but those are normally edge cases.
Upvotes: 4
Reputation: 16266
To deal with big numbers you can use the BigInteger class:
public boolean isPowerOfTwo(BigInteger n) {
if (n.compareTo(BigInteger.ZERO) <= 0) {
return false;
}
return (n.and(n.subtract(BigInteger.ONE))).equals(BigInteger.ZERO);
}
Upvotes: 2