3

下位のデータ型が上位のデータ型にキャストされることは知っていますが (例: int -> unsigned int -> float -> など)、次のことはわかりません。

int var = 5u - 10; // var = -5
auto var = 5u - 10; // var = 4294967291

5u は符号なしですが、最初のケースでは -10 (符号付き整数) が符号なしの値に変換されないのに、2 番目のケースでは変換されるのはなぜですか? 最初のケースでは、符号付きの値が符号なしの値に変換されず、これは私には奇妙です

4

4 に答える 4

4

「符号付き整数リテラル」はありません。5u - 10実際には、5u から 10 を引いたものです。

(減算の)結果は符号なしであり、オーバーフローし、結果として「オーバーフローした 0 より少ない 5 つの数値」が得られます (4294967291 = 2 32 -5) 。

最初のステートメントは an を初期化するintため、符号なしコンパイル時定数は int として再解釈されます。ハードウェアが 2 の補数演算を使用しているため、結果は正しい (-5) です。(-5 と 4294967291 は同じ 32 ビット パターンです)

2 番目のステートメントは、型がリテラルによって推測される変数を初期化します。そして、それはunsignedです。

于 2013-02-11T18:24:25.577 に答える
3

両方の例の右側は、符号なしタイプのドメインで完全に機能します。つまり、両方の式5u - 10が同じように動作しますが、同じなので驚くことではありません。どちらの場合も、式内にint(誤って想定しているように) への変換はありません。5u - 10

5u - 10は常に符号なし型のドメインで評価され、 と等しい符号なしの結果が生成されUINT_MAX + 1 - 5ます。最初の初期化では、その値を type の変数に強制しようとしますがint、その結果、実装定義の動作でオーバーフローが発生します。あなたの場合、実装varは value を取得するように動作しまし-5た。つまり、あなたが-5in になったという事実varは、抽象 C++ 言語の領域では決定的な説明がありません。観察した結果は、コンパイラの癖にすぎません。他のコンパイラでは、最初の初期化で に異なる値が生成される場合がありvarます。

2 番目のケースでは、式の型 (これもunsigned) が変数の型になり、オーバーフローのない符号なし値で初期化されます。

于 2013-02-11T18:30:21.067 に答える
2

まず第一に、を使用しているためauto、コンパイラはunsigned2 番目の例を選択します。

符号付きおよび符号なしの数値は、内部的に同じ方法で格納されます。違いを生むのは、印刷されたときに数値が解釈される方法です[比較では、「負の」符号付き数値は0未満であり、符号なし数値はゼロ未満になることはできません]-符号付き数値がチェックされますそれらが「負」の場合、マイナス記号と負の元の数値として出力されます。符号なしの数値は、印刷時に内部表現がどうなるかとして扱われます。

したがって、表示される値は、同じ数値の 2 つの異なる表現 (それぞれ符号付きと符号なし) にすぎません。

于 2013-02-11T18:22:37.327 に答える