2012-04-01 2 views
13

d이이 예제에서 b이 아닌 이유는 무엇입니까?이상한 계산 결과

unsigned int z = 176400; 
    long a = -4; 
    long b = a*z/1000; //b=4294261 
    long c = a*z; // c=-705600 
    long d = c/1000; // d =-705 

저는 Visual Studio 2008, windows XP, core2duo를 사용합니다. 감사합니다. .

+6

... d == c/1000이기 때문에. 이게 진짜 삶인가요? – outis

+2

@ crushanator 사실 a도 d와 같지 않습니다. 너 봤어? –

+3

이 예에서 1이 2가 아닌 이유는 다음과 같습니다.'int a = 1; int b = 2;'? –

답변

5

intlong이 같은 크기 인 플랫폼을 사용하고있는 것 같습니다. (나는 long 경우에 당신은 당신이보고있는 행동을 볼 것 unsigned int의 모든 유효한 값을 유지할 수 있다는 사실에 의해이 추정했습니다.)

이는 그 표현 a*z, 모두 az에서 는 unsigned long으로 변환되고 결과는 unsigned long입니다. (ISO/IEC 14882 : 2011, 5 [expr]/9 ... "그렇지 않으면 두 피연산자는 부호있는 정수 유형의 피연산자 유형에 해당하는 부호없는 정수 유형으로 변환되어야합니다.")

c is 이 표현식을 unsigned long에서 long으로 변환 한 결과, a*z의 양수 값이 부호가있는 long으로 표시되지 않으므로 구현 정의 결과가 음수가됩니다. c/1000에서 1000long으로 변환되고 long 나누기가 수행되고 (말장난 의도 없음) long (이는 음수 일 수 있음)이되고 d에 저장됩니다. 식 a*z/1000, 1000 (int 유형의 식)에

unsigned long으로 변환되고, 분할이 긍정적 인 결과로 얻어진 두 unsigned long 사이에서 수행된다. 이 결과는 long으로 표시되며 long으로 변환하고 b에 저장할 때 값이 변경되지 않습니다.

+0

이것은 사실 MS C 컴파일러의 경우입니다. – Inisheer

+0

부호있는 오버플로는 정의되지 않은 동작이지만 길입니다. –

+1

@KerrekSB : 예, 서명 된 오버 플로우가 없습니다. –