ウィキペディアで整数オーバーフローに関するこの記事を読む
符号付き整数のオーバーフローが未定義の動作を引き起こすのに、符号なし整数のオーバーフローがラップアラウンドを引き起こす理由の一部をよく理解していません.なぜそれらの動作に違いがあるのですか?
別の質問: 一般に、プログラミング言語には整数オーバーフローに対する保護機能がありますか?
ウィキペディアで整数オーバーフローに関するこの記事を読む
符号付き整数のオーバーフローが未定義の動作を引き起こすのに、符号なし整数のオーバーフローがラップアラウンドを引き起こす理由の一部をよく理解していません.なぜそれらの動作に違いがあるのですか?
別の質問: 一般に、プログラミング言語には整数オーバーフローに対する保護機能がありますか?
それが言語の定義方法だからです。これにより、より多くの種類のハードウェア(たとえば、飽和演算を備えたDSPなど)でより簡単に適合実装を開発できます。
言語によって異なります。一部のハードウェアはそうです、そしてあなたはあなたのプログラムでそれを利用することができるかもしれません。
整数オーバーフローに関する C/C++ の方法論は、作業しているマシンで最速の動作を提供することです。そのため、一部のマシンでは (ここでは 16 ビットの符号付き整数を想定しています):
32766 + 2 == -32768
しかし、一部のマシンでは次のとおりです。
32766 + 2 == 32767
他のマシンでは、トラップ値またはCPUが行うことは何でもできます。
Java では、「一度書けばどこでも実行」を実現するために、整数オーバーフローが完全に定義されています。
符号なし整数については、ほとんどのアプリケーションはビットマスク、ビットフィールド、および数値操作 (モジュロ演算、識別子) です。まさに未定義の操作ではありません。
プログラミング言語には、そのような安全対策を備えているものと、備えていないものがあります。
Python 3 は、オーバーフローした値を long 型 (任意の大きな整数) に自動変換します。
C/C++ では、オーバーフロー条件を自分で確認する必要があります。climits (C) および limits (C++) ヘッダーには、各タイプの最大値と最小値が定義されています。
x86 アセンブリでのプログラミング - 符号なしの場合は CF (キャリー フラグ)、符号付きの場合は OF (オーバーフロー フラグ) があり、オーバーフローがいつ発生したかをチェックするための FLAGS および EFLAGS レジスタがあります。
オーバーフローを回避したい場合に備えて、多くの言語には任意精度型もありますが、そのような変数は (理論上) メモリと同じ大きさになる可能性があるため、操作は遅くなります。
Java では、 unsignedint
と のlong
値のみがあり、それらの動作はどこで実行しても一貫しています。Integer.MAX_VALUE に 1 を加算すると、Integer.MIN_VALUE を賭け (ラップ)、Long.MIN_VALUE から 1 を減算すると、Long.MAX_VALUE が得られます。
したがって、符号なし値の動作が他の言語で未定義になる理由がわかりません。