블로그 이미지
짱의 꽁기꽁기 월드입니다 ㅎ Baracuda

카테고리

분류 전체보기 (4858)
Days of my life (45)
좋은 글 좋은 생각 (93)
Cartoon~ (114)
Funny, HaHa (4450)
Music~ (6)
보울~~~링 (46)
Etc (59)
Private (13)
Utility (14)
XK2 (1)
Forte Koup (5)
Total
Today
Yesterday

'unsigned int 음수'에 해당되는 글 1건

  1. 2008.01.17 unsigned int 음수 결과

unsigned int 음수 결과

Etc / 2008. 1. 17. 20:09
unsigned int 음수 결과

나도 평가하기 00

mybjunga

조회610 답변1

답변이 완료된 질문입니다. (2006-07-26 15:31 작성)

신고

아래의 소스의 두개의 출력 결과값이 어떻게 나올까요?

변화 과정을 자세히 적어주세요

특히, 두번째 결과는 정말 궁굼합니다 고수님 부탁드립니다

수고하세요


  int sx = -20;
 
  unsigned int dx = -20;

 

  printf("%d\n", sx >> 2);  

  printf("%d\n", dx >> 2);

unsigned int 음수값의 쉬프트 연산

keyseek (2006-07-26 23:32 작성)

신고|이의제기

질문자 평

조금 상세히 설명드리지요
 
먼저 sx와 dx의 메모리 내용을 볼까요?
우선 20은 2진수로 뭘까요? 32비트 정수로 본다면 다음과같습니다.
20 ==> 00000000 00000000 00000000 00010100
즉, 16진술로는 0x00000014 입니다.
 
그런데 -20은 음수표현의 2의 보수를 쓰므로
위의 20을 2의 보수를 취하면 값은 111111111 11111111 11111111 11101100 입니다.
따라서 이를 16진수로 하면? 0xFFFFFFEC 가 됩니다.
 
이 값이 int sx에 들어가면 sx의 메모리는 위의 값이 됩니다.
unsigned int dx에 들어가도 음수를 넣으니까 경고를 받겠으나
그 결과는 동일하게 sx와 같은 내용이 됩니다. 즉, ux는 0xFFFFFFEC 입니다.
 
  int sx = -20;                           => sx = 0xFFFFFFEC;
  unsigned int dx = -20;         => ux = 0xFFFFFFEC;

자, 그럼 쉬프트 연산을 하면 어떻게 될까요?
 
쉬프트 연산은 C언어에서 두가지 방식이있습니다.
 
우로 쉬프트 할때, signed 를 쉬프트 하면 부호는 다시 최상위 비트에 유지됩니다.
(이것은 -2를 우로 밀면 나누기 2가 되어 -1이 되어야 하므로
부호가 계속 유지됩니다) 이러한 쉬프트를 산술적 쉬프트라 합니다.
 
unsigned를 쉬프트 할때는 부호 개념이 없으므로 그냥 최상위에는 0이 들어옵니다.
이러한 쉬프트를 논리적 쉬프트라 합니다.
 
그러나 주의할 것은 좌로 쉬프트 할때는 signed나 unsigned나 모두
최하위비트는 0으로 채워지고 최상위비트는 그냥 밀려간다는 것입니다.
 
왜 signed에서 부호가 밀려나가도 부호가 유지되지 않을까요?
이것은 이미 최상위 비트가 밀려가면 값으로서의 의미를 상실하는
오버플로우가 발생하는 것이기 때문입니다.
 
위의 경우 signed sx를 두번 우로 밀면 부호가 유지되므로 값은?
 
메모리 내용으로는
111111111 11111111 11111111 11111011 입니다.
따라서 이를 16진수로 하면? 0xFFFFFFFB가 됩니다.
그런데 이걸 10진수타입의 signed int로 인쇄하는 %d 옵션을 쓰므로
값을 찍으면 음수이므로 - 붙이고 값은 2의 보수를 취하므로
 
-00000000 00000000 00000000 00000101이므로 즉, -5가 됩니다.
결국 -20을 나누기 2를 두번하니까 -5 되지요...
 
 
그러나 unsgned dx 를 두번 우로 밀면? 최상위에 0이 차므로
 
001111111 11111111 11111111 11111011 입니다.
따라서 이를 16진수로 하면? 0x3FFFFFFB가 됩니다.
 
이걸 signed int 타입 %d로 인쇄하면
최상위 비트가 0이므로 양수가 되고 값은?
으악 엄청 큰수가 되지요...
얼마냐면 계산기로 해보니 1073741819 가 되네요...
 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
[추가 답변]
 
그럼 왜 0x3FFFFFFB   를 signed int로 할때는
2의 보수를 취하지 않느냐고 하셨는데요...
2진수 음수표현을 좀더 정확히 공부하셔야 겠네요...
 
위의 수를 signed int로 표시하려면 즉, %d로 인쇄하라는 것은
위의 내용을 signed int로 간주하라는 겁니다.
그런데 위의 값을 이진수로 표현한것을 보면
001111111 11111111 11111111 11111011 입니다.
 
여기서 보시면 최상위 비트가 1이 아니라 0임을 알 수 있죠?
즉, 최상위 비트가 1이라면 이수는 음수라는 겁니다.
그러나 최상위 비트가 0이므로 이 수는 양수이고
그렇다면 값은 그냥 위의 값을 10진수로 표현한면 됩니다.
 
만약 위의 값이 최상위 비트가 1이었다면
프로그램에서는 이것이 음수다 라고 알게되죠
그러면 값을 알기 위하여 전체에 2의 보수를 구하여
값을 알아냅니다. (물론 마이너스이므로 -XXX 가 되겠죠)
 
그럼 다음으로 연습을 합시다.
 
지금부터 임시로 int를 8비트라고 합시다.
원래는 32비트 이지만...
 
현재 메모리의 내용이 11111100 할때
 
위의 것을 %d로 인쇄하면 뭐가 될까요?
최상위 비트가 1이므로 음수이고 값은 2의 보수를 취하므로
00000100입니다. 10진수로는 4입니다.
따라서 -4 라는 수가 되지요...
 
이걸 %u로 인쇄하여 봅시다. (%u는 unsigned int로 간주하는 겁니다)
그러면 최상위 비트가 1이지만 이것을 부호가 없는 정수로 보므로
최상위 비트는 부호가 아니라 값으로서의 1입니다.
그러므로 값은 10진수로 하여보면 10진수로 252 가 됩니다.
 
그럼 이번엔 메모리 내용이 00001111이라고 합시다
 
위의것을 %d로 인쇄하면 signed int로 간주되는데
최상위 비트(부호비트)가 0이므로 양수입니다.
이 경우는 2의 보수를 취하지 않고 그냥 전체가 값이 됩니다.
 
왜냐하면 양수를 2의 보수를 취해놓으면 반드시 최상위 비트는
1이 되기 때문에 음수로서의 원래 값을 구하려면
전체를 다시 2의 보수를 취해야 하지요...
그러나 최상위 비트가 0이면 이건 원래부터 양수이고
2의 보수로 만든수가 아니므로 값은 그냥 취하는 겁니다.
 
그래서 그 값은 15가 됩니다.
 
위의것을 unsigned int로 하면?
무조건 최상위 비트가 뭐든지 간에 양수이므로
값은 똑같이 15가 됩니다.
 
이유를 아시겠나요?
 
추가 질의에 답이 될런지요?
더 궁금하시면 쪽지요망
 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
signed 타입과 unsigned 타입의 우측쉬프트는 최상위 비트 조작이 다름을
기억해야 합니다. 가끔 실수하거든요...
 
도움이 되시길...
 
 
 
 
 
 
  printf("%d\n", sx >> 2); 
  printf("%d\n", dx >> 2);
Posted by Baracuda
, |