문제

추가 작업에서 오버플로를 일으키는 다양한 크기의 피연산자를 혼합하는 VC++2010에서 몇 가지 테스트를 수행했습니다.

int _tmain(int argc, _TCHAR* argv[])
{
    __int8 a=127;
    __int8 b=1;
    __int16 c=b+a;
    __int8  d=b+a;
    printf("c=%d,d=%d\n",c,d);

    return 0;
}

//result is: c=128, d=-128

왜 c==128인지 이해가 안 돼요!내가 이해하는 바는 두 덧셈 모두에서 b+a는 여전히 부호 있는 2의 덧셈으로 간주된다는 것입니다. 8비트 변수.따라서 결과는 오버플로입니다.-128. 이후, 결과는 첫 번째 할당 작업을 위해 16비트 부호 있는 int로 승격되고 c는 여전히 16비트 -128 값을 얻어야 합니다.내 이해가 맞나요?C++ 표준은 읽기가 약간 어렵습니다.4장은 정수 승격에 대해 이야기하는 것 같지만 이 특정 예와 관련된 내용을 찾을 수 없습니다.

도움이 되었습니까?

해결책

내가 이해한 바에 따르면 두 추가 모두에서 b+a는 여전히 2개의 부호 있는 8비트 변수의 추가로 간주됩니다.따라서 결과는 오버플로입니다.-128.

아니요, 프로모션은 다음 날짜 이전에 진행됩니다. + 그 이후가 아니라 평가됩니다.추가는 둘 다에서 발생합니다. a 그리고 b 긍정적이다.두 번호 모두 다음으로 승격됩니다. int덧셈의 ​​경우 두 개의 양수로 추가된 다음 16비트 단축으로 변환됩니다.프로세스의 어느 시점에서도 오버플로로 인해 결과가 음수가 되지 않으므로 최종 결과는 128입니다.

틀림없이 이것은 의미가 있습니다.행동 a 그리고 b 수학의 두 숫자와 일치하므로 언어 ​​실무자에게 더 직관적입니다.

다른 팁

통합홍보입니다.

1 정수 변환 순위(4.13)가 int 순위보다 작은 bool, char16_t, char32_t, wchar_t 이외의 정수 유형의 prvalue는 int가 소스 유형의 모든 값을 나타낼 수 있는 경우 int 유형의 prvalue로 변환될 수 있습니다. ;그렇지 않으면 소스 prvalue가 unsigned int 유형의 prvalue로 변환될 수 있습니다.[§ 4.5]

이 성명서에는

 __int16 c=b+a;

첫째, 모두 char 그리고 short int 값은 자동으로 다음으로 올라갑니다. int.이 과정을 통합 프로모션.다음으로 모든 피연산자는 가장 큰 피연산자의 유형으로 변환됩니다. 유형 프로모션.[허버트 쉴트]

그만큼 가치 변수의 b 그리고 a 로 승진할 것이다 int 그런 다음 작업이 적용됩니다.

2의 보수 정수 표현에서는 가장 높은 비트를 설정하여 부호 있는 값을 표현합니다.이를 통해 기계는 정수의 부호 여부에 관계없이 동일한 명령으로 이진 정수를 더하고 뺄 수 있습니다.

  a = 127 == 0x7F == 0b01111111
+ b =   1 == 0x01 == 0b00000001
-------------------------------
  c = 128 == 0x80 == 0b10000000
  d =-128 == 0x80 == 0b10000000

변수 c 그리고 d 다른 유형이 있을 수 있지만, 다른 유형의 정수는 단일 이진 값에 대한 다른 해석일 뿐입니다.위에서 볼 수 있듯이 이진 값은 8비트에 딱 맞습니다.표준에서는 수학 표현의 용어가 기계어의 크기로 0 또는 부호 확장(승격)되도록 요구하기 때문에 ~ 전에 모든 수학이 수행되고 피연산자 모두 부호 확장되지 않으며 결과는 항상 다음과 같습니다. 0b10000000 피연산자의 유형이 무엇이든 상관 없습니다.

요약하자면, 결과의 차이점은 16비트 정수에 대한 부호 비트는 다음과 같습니다. 0b1000000000000000 (어느 a+b 없음), 8비트 정수에 대한 부호 비트는 다음과 같습니다. 0b10000000 (어느 a+b 있습니다).

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