简体   繁体   English

如何检查数字<1是2的幂?

[英]How to check if a number < 1 is power of 2?

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? 例如:0.5和0.25是2的幂但0.3不是,我也知道检查整数是2的幂是否容易,但如果数字<1,如何找到数是2的幂?

public bool isPowerOf2(float number){
    if(number>1){
        //easy to write
    }else if(number==1){
        return true;
    }else{
        //hard to write
    }
}

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
}

Though using 1/x will likely work fine, one might be worried about roundoff errors. 尽管使用1 / x可能会正常工作,但人们可能会担心舍入错误。

Use Float.floatToRawIntBits(float). 使用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). 可能想检查位22是否打开但位21-0是否关闭(符号位也应为0)。 This works for both positive and negative powers of 2. The actual power is in bits 30-23. 这适用于2的正负功率。实际功率在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. 附录:如果第21位关闭,但是20-0位中的一个是正常的,则它是2的幂,如@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. 有一个众所周知的技巧可以快速测试是否设置了一个位,你可以在Stack Overflow上找到它。

Just call isPowerOf2(1.0/number); 只需调用isPowerOf2(1.0/number); in else block. else块中。 It should resolve your problem. 它应该解决你的问题。

Java uses IEEE 754 to encode floats. Java使用IEEE 754编码浮点数。 The portion from bits 22 to 0 in the binary encoding represent the mantissa (m). 二进制编码中从比特22到0的部分表示尾数(m)。 If m has exactly one 1 then the float is a power of 2. 如果m只有1,则浮点数为2的幂。

http://introcs.cs.princeton.edu/java/91float/ http://introcs.cs.princeton.edu/java/91float/

(-1)^s × m × 2^(e - 127)

Sign bit (s) (bit 31). 符号位(第31位)。 The most significant bit represents the sign of the number (1 for negative, 0 for positive). 最高位表示数字的符号(1表示负数,0表示正数)。

Exponent field (e) (bits 30 - 23). 指数字段(e)(位30-23)。 The next 8 bits represent the exponent. 接下来的8位代表指数。 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). 按照惯例,指数偏向127.这意味着为了表示二进制指数5,我们编码127 + 5 = 132二进制(10000100)。 To represent the binary exponent -5 we encode 127 - 5 = 122 in binary (01111010). 为了表示二进制指数-5,我们以二进制(01111010)编码127-5 = 122。 This convention is alternative to two's complement notation for representing negative integers. 该约定可替代表示负整数的二进制补码表示法。

Mantissa (m) (bits 22 - 0). 尾数(m)(位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. 剩余的23位代表尾数,归一化为0.5和1.这种归一化总是可以通过相应地调整二进制指数来实现。 Binary fractions work like decimal fractions: 0.1101 represents 1/2 + 1/4 + 1/16 = 13/16 = 0.8125. 二进制分数像小数部分一样工作:0.1101代表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. 例如1/10 = 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + ...在这种情况下,数字0.1近似为最接近的23位二进制分数0.000110011001100110011 ......采用了进一步的优化。 Since the mantissa always begins with a 1, there is no need to explicitly store this hidden bit. 由于尾数始终以1开头,因此无需明确存储此隐藏位。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM