C で整数オーバーフローが予期しない結果を引き起こすのはなぜですか?

DDD
リリース: 2024-11-12 16:47:01
オリジナル
213 人が閲覧しました

Why Does Integer Overflow Produce Unexpected Results in C  ?

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 の補数表現が使用されます。これは、このプログラムで観察された特定の結果を説明しています:

  • POS_MAX (正の最大値) = 7 (0111)
  • NEG_MAX (負の最大値) = -8 (1000)

に1を加える場合POS_MAX:

0111 + 1 = 1000
ログイン後にコピー

先頭ビットが設定されているため、負の数になります。実際の値を見つけるには、2 の補数逆演算を実行します。

1000 - 1 = 0111
~0111 = 1000 = -8
ログイン後にコピー

したがって、最終値は -8 となり、プログラムの出力に表示されます。

以上がC で整数オーバーフローが予期しない結果を引き起こすのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート