C++ 에서 UINT 와 int 계산규칙은 도대체 어떻게 되였는가?

C++ 에서 -10 / (UINT)5 = 858993457,  (UINT)10 / (-5) = 0 이다!

UINT m = 10;
UINT n = 5;
int s = -(int)m / n;
하면 s = 858993457
int s = m / (-(int)n);
하면 s = 0 이 된다.
이렇게 안하고도 그냥 watch 창에 -10 / (UINT)5 , (UINT)10 / (-5) 하고 넣으면
858993457 과 0 이 나온다.
이것때문에 꼬박 33분33초를 고민했다.

ps: 왜 이렇게 되는지 알려주시면 감사하겠습니다.

by 아폴로 | 2008/03/27 20:17 | 컴퓨터 | 트랙백 | 덧글(4)

트랙백 주소 : http://corapollo.egloos.com/tb/188197
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by nVec at 2008/03/27 23:02
UINT가 unsigned int를 말하는 것이라면
제 기억이 맞다면 unsigned 값과 signed 값이 연산될때는
묵시적으로 unsigned로 자동 형변환이 되는걸로 알고 있습니다.
첫번째의 경우 -10은 사실 unsinged로는 5보다 굉장히 큰값입니다
-10은 0xFFFFFFFF6 이고 5는 0x00000005 일 뿐이죠.
그래서 아마 저런 결과가 나왔을겁니다
두번째의 경우도 마찬가지죠
10, 즉 0x0000000A 를 -5, 즉 0xFFFFFFFA로 나누었으니 1 이하가 나왔을거고
저장된 자료형이 int니까 소수점은 버려져서 0이 결과가 되을겁니다.

그러니까 핵심은 unsigned와 signed가 만나서 계산하는 과정에서는
unsigned로 자동 형변환 되서 계산이 된다는 겁니다
그런 뒤에 int s에 저장될때는 또 다시 signed로 형변환이 되서 저장되겠죠.

도움이 되셨기를.
Commented by 아폴로 at 2008/03/28 00:24
댓들 남겨줘서 감사합니다.
그런데 / 연산에서만 이런 현상이 나타나고 +, -, * 에서는 제대로 결과가 나옵니다.
정확한 연산규칙을 알아야 할텐데요....
Commented by nVec at 2008/03/28 02:07
잠도 안오고 해서 직접 계산해 봤는데요 제가 말한 규칙이 맞는거 같네요
계산은 전부 unsigned로 여기고 연산한다음에 int에 저장되므로 결과를 signed로 읽어보면됩니다.
일단 + 계산부터
[-10]0xFFFFFFFF6 + [5]0x00000005 = 0xFFFFFFFB 이놈은 signed로 -5가 맞습니다
[10]0x0000000A + [-5]0xFFFFFFFB = 0x100000005 이 되는데 최상위 값은 오버플로우로 잘리고 5가 됩니다
다음 - 계산
[-10]0xFFFFFFFF6 - [5]0x00000005 = 0xFFFFFFF1 이놈은 signed로 -15 맞습니다.
[10]0x0000000A - [-5]0xFFFFFFFB = 0xFFFFFFFF0000000F 이지만 오버플로우 짤리면 15 맞습니다.
다음 * 계산
[-10]0xFFFFFFFF6 * [5]0x00000005 = 0x4FFFFFFCE 마찬가지로 오버플로우 제거하면 -50입니다
[10]0x0000000A * [-5]0xFFFFFFFB = 0x9FFFFFFCE 마찬가지로 오버플로우 제거하면 -50입니나
마지막 / 계산
[-10]0xFFFFFFFF6 / [5]0x00000005 = 0x33333331 이렇게 나오는데요
10진수로 변환하면 858993457 입니다 물론 최상위 비트는 0이므로 양수고요
[10]0x0000000A / [-5]0xFFFFFFFB = 0x0
이건 뭐 당연한 결과죠 소수 표현은 불가능 하므로 0입니다

c계열 언어들은 대부분 형이 다른 연산에서 좀더 넓은 형으로 변환되어 연산되는 경향이 있습니다
unsigned와 signed도 그런 의미로 해석하면 쉬울거 같습니다.
Commented by 아폴로 at 2008/03/28 17:57
자세히 가르쳐 주어서 감사합니다.
그러니 signed 와 unsigned 의 연산에서 unsigned 로 변환하여 처리한다는 말씀이시군요.

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶