2015-05-13 39 views
5

例如: 0.5和0.25是2的冪,但是0.3不是,我也知道檢查整數是2的冪是容易的,但如果數字是< 1,如何找到數是2的冪的?如何檢查數字<1是2的冪數?例如:

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

isPowerOf2(1/x)= isPowerOf2(x)。然而,我懷疑數字> 1的情況是以一種有用的方式「易於書寫」 –

+2

@Aakash它有什麼不清楚的地方? 「很容易檢查一個整數是否是2的冪,如何用非整數來實現呢?」 – immibis

+1

你可以用同樣的方法寫出所有的數字,但非denormals,但這可能使用一個不同的技巧比你想象的 – harold

回答

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 
} 
+0

您還需要檢查符號位是否正確? –

+0

如果意思是位解決方案,那麼它已經被檢查:'power'包含符號,並且對於負數將會超過255('255' ='Infinity')。 –

+0

是的,非常聰明:) –

0

只需撥打isPowerOf2(1.0/number);else塊。它應該解決你的問題。

3

雖然使用1/x可能會正常工作,但可能會擔心舍入誤差。

使用Float.floatToRawIntBits(float).可能要檢查第22位上,但位21-0是關閉(也標誌位應爲0)。這適用於2的正負兩個冪。實際功率位於30-23位。

附錄:如果位21關閉,但位20-0中只有一位打開,則它是2的冪,正如@anonymous所述。有一個很好的技巧來快速測試是否設置了一個位,你肯定可以在堆棧溢出的某處找到它。

+0

如果數字爲正數,則(偏)指數爲零並且在尾數中只設置一位,則數字也可以是2的冪。 –

+0

你也應該關心非規範化的數字。 –

+0

我知道有一些血淋淋的細節 - 感謝提醒! – user949300

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,我們用二進制(10000100)編碼127 + 5 = 132。爲了表示二進制指數-5,我們編碼127 - 5 = 122二進制(01111010)。這個約定是用於表示負整數的二的補碼符號的替代。

尾數(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開始,所以不需要明確地存儲這個隱藏位。

相關問題