2013-12-23 72 views
2

這是關於位操作的一些以前的問題的後續行動。我修改了代碼從this site設置N位的K(x是當前int64_t具有K位設置,並且在該代碼的末尾它與設置K比特的字典順序下一個整數)來枚舉的字符串:固有的以64位整數計算尾隨零位?

int64_t b, t, c, m, r,z; 
b = x & -x; 
t = x + b; 
c = x^t; 
// was m = (c >> 2)/b per link 
z = __builtin_ctz(x); 
m = c >> 2+z; 
x = t|m; 

使用__builtin_ctz()的修改可以正常工作,只要最低有效位位於x的較低DWORD中,但如果不是,則完全中斷。由此可以看出下面的代碼:

for(int i=0; i<64; i++) printf("i=%i, ctz=%i\n", i, __builtin_ctz(1UL << i)); 

它打印了GCC 4.4.7版本:

i=0, ctz=0 
i=1, ctz=1 
i=2, ctz=2 

...

i=30, ctz=30 
i=31, ctz=31 
i=32, ctz=0 

或ICC版本14.0.0的東西類似(除非i> 32給出隨機結果,而不是零)。在這兩種情況下,使用部分而不是2 + z的工作,但是在我的Sandy Bridge Xeon上,它的速度大約慢了5倍。我應該使用64位的其他內置函數,還是需要做一些內聯彙編程序?

謝謝!

回答

6

__builtin_ctz採用類型爲unsigned int的參數,這是大多數平臺上的32位。

如果long是64位,您可以使用__builtin_ctzl,其中需要unsigned long。或者您可以使用__builtin_ctzll,其中需要unsigned long long - 在這種情況下,您應該使用1ULL << i而不是1UL << i

+0

太好了,謝謝。正是我所期待的(關於ULL和UL,你是對的!) – Andrew