본문 바로가기

(임시휴재) Fanta's Post

Bit twiddling Hack : 정수의 부호 계산

정수의 부호 계산
경고 : 오역이 넘쳐날 수도 있어요.

int v;      // v의 부호를 찾고싶어
int sign;   // 결과는 여기에 저장됨.

// CHAR_BIT는 1바이트당 비트수를 나타낸다. (일반적으로 8).
sign = -(v < 0);  // if v < 0 then -1, else 0.

// 또는, CPU의 플래그 래지스터의 분기를 피하기 위한 방법:
sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));

// 또는, 짧은 명령 (근데 이식성은 없음.):
sign = v >> (sizeof(int) * CHAR_BIT - 1);
바로 위의 마지막 식은 32비트 정수의 sign = v >> 31의 값을 구한다. 이건 sign = -(v < 0)보다 확실히 빠른 방법 중 하나.
이 트릭은 부호있는 정수가 오른쪽으로 쉬프트연산될때 가장 왼쪽에 있는 비트의 값은 다른 비트로 복사되기때문에 작동된다.
가장 왼쪽의 비트는 정수의 값이 음수일 때 1이고, 다른 경우엔 0이다. 불행히도 이 짓거리는 컴퓨터설계자만의 특정한 경우다.

다른 방법으로, 결과가 -1또는 +1이 되길 원한다면 이걸 써:
sign = +1 | (v >> (sizeof(int) * CHAR_BIT - 1));  // if v < 0 then -1, else +1

다른 방법으로, 결과가 -1또는 0또는 +1이 되길 원한다면 이걸 써:
sign = (v != 0) | -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1));

// 또는, 약간 더 빠르지만 이식성이 낮은 방법:
sign = (v != 0) | (v >> (sizeof(int) * CHAR_BIT - 1));  // -1, 0, or +1

// 또는, 이식성도 있고, 약간 빠른 방법(아마도):
sign = (v > 0) - (v < 0); // -1, 0, or +1

경고: Angus Duggan는 부호있는 것의 right shift의 결과의 정의는 1989 ANSI C의 설명서엔 없어서 어떤 시스템에선 이 방법이 작동하지 않을 수 있다고 지적했다.(2003년 3월 7일)
Toby Speight가 CHAR_BIT는 바이트가 8비트인 것보다 더많이 쓰인다고 제안했다.(2005년 9월 28일)
Angus는 이식성이 더 좋고 캐스팅을 포함한 바로 위의 버전을 추천했다.(2006. 3월 4일)

 
copyright란 단어가 보이지 않아서 일단 해봤는 데 괜찮겠죠?
앞으로 소재고갈 염려는 없겠네요.
영어실력만 된다면요 ㅋㅋ



고닥공이 사실인가요.jpg

'(임시휴재) Fanta's Post' 카테고리의 다른 글

비트연산 활용  (0) 2009.03.21
최대공약수와 최소공배수  (0) 2009.03.14
변수의 범위  (3) 2009.02.21
시간복잡도  (4) 2009.02.14
포스팅연기  (1) 2009.02.11