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

时间:2015-05-13 06:03:04

标签: java algorithm math

例如: 0.5和0.25是2的幂但是0.3不是,我也知道检查整数是2的幂是否容易,但是如果数字< 1?

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

4 个答案:

答案 0 :(得分:7)

试试这个解决方案:

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;
}

顺便说一句,你可以通过检查浮点二进制表示的位来解决这个问题:

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
}

答案 1 :(得分:3)

虽然使用1 / x可能会正常工作,但人们可能会担心舍入错误。

使用Float.floatToRawIntBits(float).可能想要检查位22是否打开但位21-0是否已关闭(符号位也应为0)。这适用于2的正负功率。实际功率在30-23位。

附录:如果第21位关闭,但是20-0位中的一个是正常的,则它是2的幂,如@anonymous所述。有一个众所周知的技巧可以快速测试是否设置了一个位,你肯定可以在Stack Overflow上找到它。

答案 2 :(得分:0)

只需在SELECT receipt_date, SUM(CASE WHEN receipt_no like '%CA%' THEN receipt_amount END) [Cash Receipt], SUM(CASE WHEN receipt_no like '%CC%' THEN receipt_amount END) [CreditCard Receipt], SUM(CASE WHEN receipt_no like '%CH%' THEN receipt_amount END) [Cheque Receipt] FROM rpt_receipt_hdr GROUP BY receipt_date 块中调用isPowerOf2(1.0/number);即可。它应该可以解决你的问题。

答案 3 :(得分:0)

Java使用IEEE 754编码浮点数。二进制编码中从比特22到0的部分表示尾数(m)。如果m只有1,则浮点数为2的幂。

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

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

符号位(第31位)。最重要的位代表数字的符号(1为负数,0为正数)。

指数字段(e)(位30-23)。接下来的8位代表指数。按照惯例,指数偏向127.这意味着为了表示二进制指数5,我们编码127 + 5 = 132二进制(10000100)。为了表示二进制指数-5,我们以二进制(01111010)编码127-5 = 122。此约定可替代表示负整数的二进制补码表示法。

尾数(m)(位22-0)。剩余的23位代表尾数,归一化为0.5和1.这种归一化总是可以通过相应地调整二进制指数来实现。二进制分数像小数部分一样工作:0.1101代表1/2 + 1/4 + 1/16 = 13/16 = 0.8125。并非每个十进制数都可以表示为二进制分数。例如1/10 = 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + ...在这种情况下,数字0.1近似为最接近的23位二进制分数0.000110011001100110011 ......采用了进一步的优化。由于尾数始终以1开头,因此无需明确存储此隐藏位。