문제

C에서 다음 코드를 실행하면 :

#include <stdint.h>

uint16_t a = 4000;
uint16_t b = 8000;

int32_t c = a - b;

printf("%d", c);

결과적으로 '-4000'을 올바르게 인쇄합니다. 그러나 나는 약간 혼란 스럽다 : 다른 사람으로부터 더 큰 서명되지 않은 정수를 빼면 산술 오버플로가 없어야합니까? 여기서 어떤 캐스팅 규칙이 작용합니까? 이 질문은 약간 oobish처럼 보이므로 모든 참조는 크게 감사 할 것입니다.

도움이 되었습니까?

해결책

문제는 실제로 다소 복잡합니다. 산술 표현의 피연산자는 3.2.1.5 절에서 볼 수있는 특정 규칙을 사용하여 변환됩니다. 표준 (C89). 귀하의 경우 대답은 유형에 따라 다릅니다. uint16_t 이다. 그것이 더 작다면 int, 말하다 short int, 그런 다음 피연산자가 변환됩니다 int 그리고 당신은 -4000을 얻지 만 16 비트 시스템에서는 uint16_t 할 수 있습니다 unsigned int 서명 된 유형으로의 변환은 자동으로 발생하지 않습니다.

다른 팁

짧은 대답은 이것들이 모두 홍보된다는 것입니다. int 빼기 동안. 긴 대답은 6.3.1.1 절을보십시오. C 표준, 그것이 이야기하는 곳 정수 프로모션 산술 표현. 표준의 관련 언어 :

만약 int 원래 유형의 모든 값을 나타내면 값은 int; 그렇지 않으면, 그것은 An으로 변환됩니다 unsigned int. 이것들은 정수 프로모션. 다른 모든 유형은 정수 프로모션으로 변경되지 않습니다.

세부 사항도 거기에 있지만 꽤 불쾌합니다.

두 피연산자 모두 홍보됩니다 int32_t 빼기 동안. 결과가 최대 값보다 큰 경우 int32_t 당신은 오버플로를 보았을 것입니다.

실제로 오버플로가 있지만 C는 말하지 않습니다.

오버 플로우는 서명 된 정수로 해석 될 때 -4000 인 값을 남깁니다. 이것은 2의 보완 기계에서 설계된대로 작동합니다.

결과를 서명되지 않은 것으로 해석하면 U1 <u2 일 때 (U1-U2)가 겉보기에 관련이없는 숫자로 평가됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top