C언어 bit연산 질문입니다.
글쓴이: choboja / 작성시간: 수, 2010/12/01 - 10:30오전
C언어 비트연산 질문입니다.
일단 첫번째 출력은 0xffffffffffffffff 이구요.
제가 원한 두번째 출력은 64bit 를 모두 left shift시키니 0을 예상했는데,
두번째 출력역시 0xffffffffffffffff 나오는군요.
원래 C언어의 shift는 0을 패딩하지 않나요?
왜 이런 결과가 나오는걸까요?
답변 부탁드릴께요.
#define ALL_SET_BIT (0-1UL) int main() { unsigned long long down_side = 0; down_side = ALL_SET_BIT; printf("%llx\n", down_side); printf("%llx\n", down_side << 64); return 0; }
Forums:
64비트를 shift해서 그런 것 같습니다. 잘못된
64비트를 shift해서 그런 것 같습니다. 잘못된 실행이라고 간주해버리는 거죠. (compile-time warning 발생합니다.)
32비트나 63비트만 shift해보시죠.
네 맞습니다.
64보다 작은 수를 shift시에는 정상 동작합니다.
하지만 64의 배수면 위와 같은 상황이 발생하네요.
일단 이런식으로 사용을 하고 있는데, 이유를 알고싶네요.
맞는 지 틀린 지는 직접 찾아보세요. 주워 들은 것만
맞는 지 틀린 지는 직접 찾아보세요.
주워 들은 것만 옮깁니다.
C 의 경우 n bit 에 대한 shift 연산은 n-1 까지만 유효합니다.
그 이상은 undefined 입니다.
컴파일러 제작자가 심혈을 기울여 모든 예외처리를 해 줄 수도 있고,
그냥 CPU 에게 던져버리고 신경쓰지 않을 수도 있습니다.
x86 의 경우 5bit 혹은 6bit 를 mask 해서 사용합니다.
쿨한 컴파일러가 x86 에게 던져주고 신경 끈 경우라면,
64 건 128 이건 0 과 동일한 결과를 보게 되실겁니다.
65 건 129 이건 1 과 동일한 결과를 보게 되실거고요.
x86에서만 그런갑다 싶은데요.
원인은 x86의 SHL명령에 있지 싶습니다.
http://www.vikaskumar.org/amd64/bitshift.htm
보시면,
shift 명령시에 count에 해당되는 CL값이
32bit에서는 하위 5bit만, 64bit에서는 하위 6bit만 사용되도록 mask된다는 것입니다.
그래서,
down_side << 64
는
down_side << (64 & 0x3F)
이렇게 되는거죠.
언어 정의에, 해당 타입의 비트 수보다 작은
언어 정의에, 해당 타입의 비트 수보다 작은 수치만큼만 shift가 가능하다고 나와 있습니다.
6.5.7.3 ...The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
필요시 CHAR_BIT 매크로를 써보기 바랍니다. 예를 들면 "something << (CHAR_BIT * sizeof(long) - 1)" 꼴로...
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
제가 알기론..
부호비트에 1로 셋팅 된 변수를 left로 shift하면 무조건 맨 오른쪽 비트는 1로 셋팅 된다고 알고 있습니다.
즉 비트가
01234567......63 위치
11111111.......1
로 되어 있고 왼쪽으로 시프트 하면
.........01234567........63
1 <-- 11111111........1
↑0번째 bit
이렇게 된다고 합니다.
C언어 책에서 본 건데 C언어가 컴파일러 마다 달리 동작하겠지만 뭐 그렇게 동작한다고 하더군요.
당신 무엇을 아는가?
난 아무것도 모르네;;;;
댓글 달기