Reputation: 7867
for example: 0.5 and 0.25 is power of 2 but 0.3 is not, also I know checking if integer is power of 2 is easy, but how to find if number is power of 2 if the number < 1?
public bool isPowerOf2(float number){
if(number>1){
//easy to write
}else if(number==1){
return true;
}else{
//hard to write
}
}
Upvotes: 7
Views: 980
Reputation: 9085
Java uses IEEE 754 to encode floats. The portion from bits 22 to 0 in the binary encoding represent the mantissa (m). If m has exactly one 1 then the float is a power of 2.
http://introcs.cs.princeton.edu/java/91float/
(-1)^s × m × 2^(e - 127)
Sign bit (s) (bit 31). The most significant bit represents the sign of the number (1 for negative, 0 for positive).
Exponent field (e) (bits 30 - 23). The next 8 bits represent the exponent. By convention the exponent is biased by 127. This means that to represent the binary exponent 5, we encode 127 + 5 = 132 in binary (10000100). To represent the binary exponent -5 we encode 127 - 5 = 122 in binary (01111010). This convention is alternative to two's complement notation for representing negative integers.
Mantissa (m) (bits 22 - 0). The remaining 23 bits represent the mantissa, normalized to be between 0.5 and 1. This normalization is always possible by adjusting the binary exponent accordingly. Binary fractions work like decimal fractions: 0.1101 represents 1/2 + 1/4 + 1/16 = 13/16 = 0.8125. Not every decimal number can be represented as a binary fraction. For example 1/10 = 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + ... In this case, the number 0.1 is approximated by the closest 23 bit binary fraction 0.000110011001100110011... One further optimization is employed. Since the mantissa always begins with a 1, there is no need to explicitly store this hidden bit.
Upvotes: 0
Reputation: 15729
Though using 1/x will likely work fine, one might be worried about roundoff errors.
Use Float.floatToRawIntBits(float).
You probably want to check that bit 22 is on but bits 21-0 are off (also the sign bit should be 0). This works for both positive and negative powers of 2. The actual power is in bits 30-23.
Addendum: if bit 21 is off, but exactly one of bits 20-0 are on, it is a power of 2, as mentioned by @anonymous. There is a well know trick to quickly test if exactly one bit is set, which you can surely find somewhere on Stack Overflow.
Upvotes: 3
Reputation: 100349
Try this solution:
public boolean isPowerOf2(float number){
if(number>1){
//easy to write
}else if(number==1){
return true;
}else if(number>0){
return isPowerOf2(1.0f/number);
}else
return false;
}
By the way you can solve this simply by checking the bits of float binary representation:
public static boolean isPowerOfTwo(float i) {
int bits = Float.floatToIntBits(i);
if((bits & ((1 << 23)-1)) != 0)
return ((bits & (bits-1)) == 0); // denormalized number
int power = bits >>> 23;
return power > 0 && power < 255; // 255 = Infinity; higher values = negative numbers
}
Upvotes: 7
Reputation: 7045
Just call isPowerOf2(1.0/number);
in else
block. It should resolve your problem.
Upvotes: 0