2010-05-23 50 views
8

如果你有二進制數10110,我怎樣才能讓它返回11111?例如,設置所有位爲1的第一1後一個新的二進制數,也有下列一些同樣的例子:獲取int中使用的位的長度

101應返回111(3位長) 011應返回11(2位長) 11100應返回11111(5位長度) 101010101應該返回111111111(9位長度)

這怎麼能在Java中獲得最簡單的方式?我可以想出一些方法,但他們不是很「漂亮」。

+3

這一切都在這裏:http://graphics.stanford.edu/~seander/bithacks.html – 2010-05-23 13:44:14

回答

6

您可以使用此代碼:

int setBits (int value) 
{ 
    value |= (value >> 1); 
    value |= (value >> 2); 
    value |= (value >> 4); 
    value |= (value >> 8); 
    value |= (value >> 16); 
    return value; 
} 

的想法是,最左邊的1將會被複制到所有位置正確的。

編輯:也工作正常與否定value。如果您將int替換爲long,請再添加一個|=聲明:value |= (value >> 32)。一般來說,最後一次移位必須是2的冪,其至少是大小的一半(以位爲單位)。

+2

該算法特別好用的是它重用了以前的操作。天真地,我只做了32班。 – 2010-05-23 13:52:15

+1

如果您在JDK中查看'Integer#highestOneBit()'的實現,您將看到相同的算法,儘管最後一步是量身定製的,只能提供一個位,需要在hleinone的答案中捕獲撤消。 – seh 2010-05-23 14:17:10

6

沒有測試,但是這樣的事情應該沒有問題:

long setBits(long number) { 
    long n = 1; 
    while (n <= number) n <<= 1; 
    return n - 1; 
} 
+0

+1用於外箱的思維:-) – 2010-05-23 13:49:50

+1

這不會工作,如果'號碼是否定的。如果'number'通常很小,那麼速度會很快,但如果'number'大致均勻地分佈在它的範圍內,速度會很慢。 – doublep 2010-05-23 13:54:07

+0

對於負面情況,我沒有想到。如果我從另一端開始,平均速度會更快。但63次迭代(最大)並不是那麼慢;答案就在我頭頂。顯然,hleinone的解決方案將它從水中吹出來...... :) – Amadan 2010-05-23 15:43:43

0

不是最有效的,但最簡單的,

int i = (1 << (int)(Math.log(n)/Math.log(2)+1)) - 1; 

它將爲INT的第31位和第63位長期工作。

10
+0

爲了完整性:http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Integer.html#highestOneBit(int) – Eric 2010-05-23 14:04:02

+0

嗯..看起來我不能發佈鏈接。 SO不喜歡括號。 – Eric 2010-05-23 14:05:31

+3

哇,不知道Java有這個功能......這在這裏絕對是最重要的。 – Amadan 2010-05-23 15:17:54