10

MinGW の GCC でコンパイルされた Windows7 x64 で次のコードを実行すると、結果がアンダーフローするようです。

cout<<-2147483648 ;    //Output: 2147483648

しかし、それを整数変数に割り当てたとき、または単に int 型に変換したとき:

cout<<(int)-2147483648 ; //Output: -2147483648 

では、以前のバージョンのコードの何が問題になっているのでしょうか? int型じゃないの?または、整数の下限は正確には何ですか? どうもありがとう。

4

4 に答える 4

11

2147483648 はシステムの int または long に適合しないため、unsigned long 型の定数として扱われます。(編集: ouah がコメントで指摘したように、標準 C++ では未定義の動作ですが、コンパイラはそれを拡張機能として受け入れます。) 符号なし整数値を否定することは可能ですが、別の符号なし整数値になり、負の数になることはありません。2147483648UL を否定すると、2147483648UL が生成されます (システムの場合と同様に、unsigned long が 32 ビット型であると仮定します)。

それをにキャストするとint、実装定義の結果が生成されます。通常は表示される結果ですが、必ずしもそうとは限りません。-2147483647 - 1 と書くことで、変換なしで必要な結果を得ることができます。

于 2012-09-27T11:57:13.923 に答える
3

では、以前のバージョンのコードの何が問題になっているのでしょうか?

おそらく、2011年より前のコンパイラを使用しており、システムlongには32ビットがあります。値 (-2 31 ) が に収まるとは限らないlongため、オーバーフローする可能性があります。これにより未定義の動作が発生するため、何でも見ることができます。

表示される特定の値 (2 31 )の最も可能性の高い説明は、C++ で定義された動作がないため、コンパイラが古い C90 規則を使用し、値を に変換していることunsigned longです。

int型じゃないの?

2011 年より前はint、値が で表現できる場合int、それ以外longの場合は未定義の動作で十分でない場合でした。C++11 は型を追加し、十分な大きさでないlong long場合に整数リテラルに使用できるようにします。long

または、整数の下限は正確には何ですか?

N ビットの符号付き整数型の範囲は、少なくとも -2 (N-1) +1 から 2 (N-1) -1 です。あなたの値は -2 31で、これは 32 ビット符号付きタイプの範囲外です。

言語は整数型の正確なサイズを指定しません。それにintは、少なくとも 16 ビット、long少なくとも 32 ビット、および (2011 年以降)long long少なくとも 64 ビットが必要です。

于 2012-09-27T12:32:27.237 に答える
2

まず、負の整数リテラルがないことを理解することが重要です。

OPの特定のコンパイラがそのように動作する理由を他の人が説明しています。ただし、記録のために、これはコンパイラが32 ビット システムで行間で行うべきことです。

  • intあなたの番号は 2147483648 で、 2 の補数形式の32 ビット符号付きには収まりません。
  • これは 10 進数であるため (U、L などの接尾辞が付いていない)、コンパイラは内部型テーブル (1) でそのような整数定数をチェックします。これは次のように機能します: に収まるようにします。収まらない場合は をint試しlong、そこにも収まらない場合は を試し、どちらにもlong long収まらない場合は、未定義の動作をします。最新の標準に準拠する AC または C++ コンパイラは、符号なしの型に適合させようとしません。
  • intこの特定のケースでは、数値が a にも aにも収まらないlongため、コンパイラはlong longリテラルの as 型を使用することを決定します。
  • 次に、このリテラルに単項マイナス演算子を使用すると、数値 -2147483648 になります。皮肉なことに、これは 2 の補数形式の signed int に適合しますが、型を変更するには遅すぎます。コンパイラは既にlong long型として選択しています。

(1) この「内部テーブル」は、符号なし接尾辞がある場合、または 16 進形式などの場合は異なって見えます。符号なし接尾辞がある場合は、数値が符号なし数値に収まるかどうかのみをチェックします。16 進数表記がある場合 (接尾辞がない場合)、int、unsigned int、long の順にチェックされます。

于 2012-09-27T13:10:40.097 に答える
0

実際に、CS:APP の pdf ファイルから説明を見つけました。これは完全に解決策を提供します。ここからダウンロードできます。http://www.csapp.cs.cmu.edu/public/waside/waside-tmin.pdf

于 2012-10-02T04:42:57.197 に答える