C での整数オーバーフローによる予期しない結果
整数型を扱う場合、オーバーフローの影響を理解することが不可欠です。この投稿では、C プログラムで符号付き整数オーバーフローと符号なし整数オーバーフローが予期しない結果をもたらす理由を検討します。
整数オーバーフローをテストする次のプログラムを考えてみましょう:
#include <iostream> int main() { int x(0); std::cout << x << std::endl; x = x + 2147483647; std::cout << x << std::endl; x = x + 1; std::cout << x << std::endl; std::cout << std::endl; unsigned int y(0); std::cout << y << std::endl; y = y + 4294967295; std::cout << y << std::endl; y = y + 1; std::cout << y << std::endl; }
出力は驚くべきものです:
0 2147483647 -2147483648 0 4294967295 0
符号付き整数オーバーフロー
符号付き整数のオーバーフローは未定義の動作です。これは、コンパイラが、この場合のように不正な結果を生成することも含めて、やりたいことを何でもできることを意味します。
符号なし整数オーバーフロー
対照的に、符号なし整数オーバーフローは適切です。 -定義されています。値は 2^bits によるモジュロ除算に似て、ラップアラウンドします (bits はデータ型のビット数です)。 32 ビット int があるため、
4294967295 + 1 = 4294967296 % 2^32 = 0
特定の実装の詳細
符号付き整数のオーバーフローは未定義の動作ですが、ほとんどの実装では 2 の補数表現が使用されます。これは、このプログラムで観察された特定の結果を説明しています:
に1を加える場合POS_MAX:
0111 + 1 = 1000
先頭ビットが設定されているため、負の数になります。実際の値を見つけるには、2 の補数逆演算を実行します。
1000 - 1 = 0111 ~0111 = 1000 = -8
したがって、最終値は -8 となり、プログラムの出力に表示されます。
以上がC で整数オーバーフローが予期しない結果を引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。