2013-12-23 5 views
2

이것은 비트 조작에 대한 몇 가지 이전 질문에 대한 후속 조치입니다.64 비트 정수에서 후행 0 비트를 카운트하는 내장 함수?

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; 
: I 세트 N 비트를 K (x는 세트 K 비트와 현재 int64_t이며, 코드의 끝이 세트 K 비트와 전적으로 다음 정수)로 문자열을 열거 this site의 코드를 수정

__builtin_ctz()을 사용하는 수정은 최하위 비트가 x의 하위 DWORD에있는 한 올바르게 작동하지만, 그렇지 않은 경우 완전히 중단됩니다. 이것은 다음과 같은 코드를 볼 수 있습니다 : GCC 버전 4.4.7에 대한 인쇄

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

:

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는 무작위 결과를 나타내며 0은 아님). 2 + z로 이동하는 대신에 나누기를 사용하면 두 경우 모두 작동하지만 내 Sandy Bridge Xeon에서는 약 5 배 느립니다. 64 비트 용으로 사용해야하는 다른 내장 함수가 있습니까? 아니면 인라인 어셈블러를 사용해야합니까?

감사합니다.

답변

6

__builtin_ctz은 대부분 플랫폼에서 32 비트 인 unsigned int의 인수를 취합니다.

long이 64 비트 인 경우 __builtin_ctzl을 사용하면 unsigned long이됩니다. 또는 __builtin_ctzllunsigned long long을 사용할 수 있습니다.이 경우 1UL << i 대신 1ULL << i을 사용해야합니다.

+0

감사합니다. 내가 찾고 있었던 바로 그 것 (그리고 ULL 대 UL! Doh! – Andrew