2016-11-23 60 views
0

由於掩碼的大小爲size我想創建一個long mask掩碼集的底部size位,高位爲零。例如,size == 4的掩碼爲0b1111(又名0x0000000000000000F),依此類推。 size必須在0 <= size <= 64的範圍內。給定一個掩碼大小,高效地創建一個低位設置的掩碼

未對所有輸入糾正一個典型的嘗試如下:

long makeMask(int size) { 
    return (1L << size) - 1; 
} 

...但失敗了大小== 64,返回0,而不是預期的全1: 0xFFFFFF....。對於int口罩,我可以將其轉換爲long以避免此問題,但對於long,我看不到類似的解決方法。

我可以這樣做:

long makeMask(int size) { 
    return size == 64 ? -1L : (1L << size) - 1; 
} 

...但我真的想避免出現不可預測的分支。

+1

也許你可以嘗試將此[C++答案](http://stackoverflow.com/a/28703383/5517612)轉換爲Java? –

+1

總會有邊界問題。在64和@ LukeLee的零點之間選擇你的。或者製作查找表。 – EJP

+0

@ToddSewell - 對,但這兩個解決方案歸結爲像我上面的條件(或有條件的移動,如減少條件,例如,' - (size!= 0)&...'。 – BeeOnRope

回答

3

您可以使用第7位取反,並移:

long x = (size >> 6)^1; 
return (x << size) - 1; 

size = 64這臺x = 0(0 << whatever) - 1顯然是-1。

在其他情況下,它簡化爲舊的(1L << size) - 1

+0

這真令人印象深刻! –

+0

我沒有找到更好的,所以接受這一個。 – BeeOnRope