2012-11-16 34 views
5

我使用64位整數中的位存儲標誌。
我想知道是否有一個位設置在64位整數內的任何位置(例如,我不關心任何特定位的位置)。檢查一個整數中是否只設置了一個位(無論其位置)

boolean isOneSingleBitSet (long integer64) 
{ 
    return ....; 
} 

我可以指望使用Bit Twiddling Hacks (by Sean Eron Anderson)位數,但我想知道什麼是隻檢測一個單個位是否設置最有效的方式...

我發現了一些其他的相關問題:

,也有一些維基百科頁面:

NB:我的應用程序是在Java中,但我用其他語言很好奇優化...


編輯Lưu Vĩnh Phúc指出我的第一個鏈接在我的問題中已經得到了答案:請參閱Determining if an integer is a power of 2Bit Twiddling Hacks(作者:Sean Eron Anderson)。我沒有意識到單個位相同兩個功率

+1

對於Java我會考慮使用位集合類用於此目的,它支持方便的isEmpty()方法,以及許多其他製造位標誌更容易使用。 – maximdim

+1

它已經在上面鏈接的Bit Twiddling Hacks中:[確定一個整數是2的冪](http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2) –

+0

哦!謝謝:-)我更新我的問題:-)乾杯 – olibre

回答

14

如果你只是從字面上要檢查,如果一個單位,那麼你基本上是檢查,如果數量是2的冪要做到這一點,你可以這樣做:

if ((number & (number-1)) == 0) ... 

這也將算0作爲2的冪,所以你應該檢查數字不是0,如果這很重要。所以後來:

if (number != 0 && (number & (number-1)) == 0) ... 
+0

完美答案! – Ali

+0

我很抱歉,但我測試了你的答案,我有這些結果:'0'->'false'(** ok **); '1'->'true'(** ok **); '2'->'false'(** KO **); '3'->'false'(** ok **); '4'->'false'(** KO **)'5'->'false'(** ok **)...請您也可以檢查一下嗎? – olibre

+0

看看第二個版本,我已經詳細說明了如何使用!= 0的檢查來查看它。真的很好,就我所見。 –

1

假設你已經有一個有效的 - 或硬件 - 實施ffs() - 發現第一組 - 你可以按照如下作用:

bool isOneSingleBitSet (long integer64) 
{ 
    return (integer64 >> ffs(integer64)) == 0; 
} 

ffs()功能可能已經可用,或者您可能會看到your own link above

+0

是'ffs()'在Java中可用? – olibre

+0

+1你的答案是有效的:-),但使用GCC'__builtin_ffs()'進行測試。請告訴我,如果'ffs()'在java中可用... – olibre

+0

我不是一個Java開發人員!只是對您的問題感興趣 – Ali

2

包裝類java.lang.Long有一個靜態函數bitCount()返回在長(64位INT)的比特數:

boolean isSingleBitSet(long l) 
{ 
    return Long.bitCount(l) == 1; 
} 

請注意,整數是java中的32位。

+2

將條件更改爲== 1,這將起作用,但嚴格來說,它幾乎肯定不是檢測單個比特的最有效方式。 –

+0

你知道這種方法的開銷嗎?即使不是最快的,這也是最可讀的解決方案。 –

+0

現在('> 0'),這將檢查數字是否爲非零(感謝@NeilCoffey注意)。 –

0

好像你可以做的位與要檢查單個位的long表示。例如,要檢查LSB

return( (integer64 & 1L)!=0 ); 

或檢查從右側

return( (integer64 & 8L)!=0 ); 
+0

好的......但你如何檢查是否有一個單一的位集?你檢查每個64位? – olibre

+1

在這個答案中使用的方法,是的,但我不會推薦它。我將最初的問題理解爲檢查特定位,而不是像預期的那樣檢查任何單個位。你打算這個問題更有意思,Neil Coffey和Jan Dvorak也很好地回答了這個問題。 – Pursuit

+0

謝謝@Pursuit。我會改進一點,我的問題更容易理解;-) – olibre

1

讓我們假設X中的第4位是64位全間0 exept你正在尋找一個的;

return ((64bitinteger&X)==X) 
+0

在64bitinteger = 0時返回true :-( – olibre

+0

什麼是答案中的「X」?與「64bitinteger」相同? – olibre

+0

1010101如果您想檢查如果第三位是1 1010101&0010000等於0010000 在這個例子中X = 0010000 – Ercan

15

(使用x作爲自變量)

如果至少有一個位被置位檢測很容易:

return x!=0; 

同樣檢測是否被設置的位一個(第二最低位)是很容易:

return (x&2)!=0; 

如果它是2的冪,則確切地設置一位。這工作:

return x!=0 && (x & (x-1))==0; 
+0

有沒有什麼辦法可以檢查哪個位在?(旁邊有log)很好用的技巧 – hl3mukkel

+0

@ hl3mukkel你可以使用迭代除法(這只是一種計算整數對數的方法)如果你正在尋找更快的東西,請檢查http://stackoverflow.com/q/14429661/499214。使用對數肯定更具可讀性,受roundi問題。 –

+0

謝謝!我發現[鏈接](http://stackoverflow.com/a/20342282/2489327)是一種高效且乾淨的方法。 – hl3mukkel

相關問題