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를 사용합니다. 감사합니다. .
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를 사용합니다. 감사합니다. .
int
과 long
이 같은 크기 인 플랫폼을 사용하고있는 것 같습니다. (나는 long
경우에 당신은 당신이보고있는 행동을 볼 것 unsigned int
의 모든 유효한 값을 유지할 수 있다는 사실에 의해이 추정했습니다.)
이는 그 표현 a*z
, 모두 a
및 z
에서 는 unsigned long
으로 변환되고 결과는 unsigned long
입니다. (ISO/IEC 14882 : 2011, 5 [expr]/9 ... "그렇지 않으면 두 피연산자는 부호있는 정수 유형의 피연산자 유형에 해당하는 부호없는 정수 유형으로 변환되어야합니다.")
c
is 이 표현식을 unsigned long
에서 long
으로 변환 한 결과, a*z
의 양수 값이 부호가있는 long
으로 표시되지 않으므로 구현 정의 결과가 음수가됩니다. c/1000
에서 1000
은 long
으로 변환되고 long
나누기가 수행되고 (말장난 의도 없음) long
(이는 음수 일 수 있음)이되고 d
에 저장됩니다. 식 a*z/1000
, 1000
(int
유형의 식)에
는 unsigned long
으로 변환되고, 분할이 긍정적 인 결과로 얻어진 두 unsigned long
사이에서 수행된다. 이 결과는 long
으로 표시되며 long
으로 변환하고 b
에 저장할 때 값이 변경되지 않습니다.
이것은 사실 MS C 컴파일러의 경우입니다. – Inisheer
부호있는 오버플로는 정의되지 않은 동작이지만 길입니다. –
@KerrekSB : 예, 서명 된 오버 플로우가 없습니다. –
... d == c/1000이기 때문에. 이게 진짜 삶인가요? – outis
@ crushanator 사실 a도 d와 같지 않습니다. 너 봤어? –
이 예에서 1이 2가 아닌 이유는 다음과 같습니다.'int a = 1; int b = 2;'? –