2

a + b予想どおり 255 が 4 にオーバーフローし、予想どおりc / 22 が返されます。しかし、同じ 2 つのステップを評価するときに最後の例がオーバーフローしないのはなぜでしょうか?

内部計算値はより多くのビットで保存され、割り当てを行うときに8ビットに切り捨てられるだけだと思います。その場合、限界はどこにあるのでしょうか。

uint8_t a = 250;
uint8_t b = 10;
uint8_t c = (a + b);
uint8_t d = c / 2;
uint8_t e = (a + b) / 2;

std::cout << unsigned(c) << ", " << unsigned(d) << ", " << unsigned(e) << "\n";

4、2、130

4

4 に答える 4

2

インテグラルプロモーションといいます。int操作自体は、255 を超える数値を保持できるCPU ネイティブの整数型 で実行されます。このa+b場合、結果は に格納する必要がありuint8_t、そこで切り捨てが行われます。最後のケースでは、最初に として行われる除算がintあり、結果は に完全に格納できますuint8_t

于 2016-04-11T05:49:11.937 に答える
0

@atturriは正しいです。x86 機械語の変数は次のようになります。

REP STOS DWORD PTR ES:[EDI]
MOV BYTE PTR SS:[a],0FA
MOV BYTE PTR SS:[b],0A
MOVZX EAX,BYTE PTR SS:[a] ; promotion to 32bit integer
MOVZX ECX,BYTE PTR SS:[b] ; promotion to 32bit integer
ADD EAX,ECX
MOV BYTE PTR SS:[c],AL ; ; demotion to 8bit integer
MOVZX EAX,BYTE PTR SS:[c]
CDQ
SUB EAX,EDX
SAR EAX,1
MOV BYTE PTR SS:[d],AL
MOVZX EAX,BYTE PTR SS:[a]
MOVZX ECX,BYTE PTR SS:[b]
ADD EAX,ECX
CDQ
SUB EAX,EDX
SAR EAX,1
MOV BYTE PTR SS:[e],AL
于 2016-04-11T07:58:36.303 に答える
0

以下(a + b)ではオーバーフローしません。コンパイラはaandbを整数型として認識します。したがって、加算の結果は整数型になります。この式の結果は、式の項または係数のサイズによって制限されません。

aorのような変数の型を想定してみましょbう。この場合、結果はその型のみに制限されます。可能ではあるものの、このような言語を使用することはほとんど不可能です。型を考慮しない場合、合計が 500 になる 5 つの変数を想像してみてください。

uint8_t a = 98;
uint8_t b = 99;
uint8_t c = 100;
uint8_t d = 101; 
uint8_t e = 102;

上記の変数の合計 == 500. さて... 以下では、式の結果はいずれかの項のサイズを超えることはできません...

int incorrect = (a + b + c + d + e);

この場合(a + b + c) == 41(41 + d + e)== 244.これは無意味な答えです..ほとんどの人が認識している代替案

(98 + 99 + 100 + 101 + 102) == 500;

これが、型変換が存在する理由の 1 つです。

式の中間結果は、式の項や要素によって制限されるのではなく、結果の型、つまり左辺値によって制限されるべきです。

于 2016-04-11T07:54:15.937 に答える
0

a+bどのタイプにも割り当てられていない値 260 を与えるuint8_tので、最後のケースでは問題ありません。255 より大きい値を代入した場合にのみuint8_t、オーバーフローが発生します。

于 2016-04-11T05:48:23.017 に答える