整数オーバーフロー エラーとは何ですか? なぜ私はそのようなエラーを気にするのですか? それを回避または防止する方法にはどのようなものがありますか?
10 に答える
整数型が処理できる最大数よりも大きい数値を表現しようとすると、整数オーバーフローが発生します。
数値 300 を 1 バイトで表現しようとすると、整数オーバーフローが発生します (最大は 255)。2 バイトで 100,000 も整数オーバーフローです (最大値は 65,535)。
数学演算は期待どおりに動作しないため、注意する必要があります。整数オーバーフローがある場合、A + B は実際には A と B の合計と等しくなりません。
最初に条件を作成しないことでこれを回避します (通常は、オーバーフローしないように十分な大きさの整数型を選択するか、オーバーフローが発生しないようにユーザー入力を制限することによって)。
それを説明する最も簡単な方法は、簡単な例を使用することです。4 ビットの符号なし整数があるとします。0 は 0000 になり、1111 は 15 になります。したがって、16 を取得する代わりに 15 をインクリメントすると、16 は実際には 10000 であり、5 ビット未満では表現できないため、0000 に戻ります。だからオーバーフロー...
実際には、数字ははるかに大きく、int が署名されている場合、オーバーフロー時に大きな負の数になりますが、基本的には上記のようになります。
別の見方をすると、車の走行距離計が 999999 km/mi に達した後、再びゼロになったときに起こることとほとんど同じであると考えることができます。
整数をメモリに格納すると、コンピューターはそれを一連のバイトとして格納します。これらは一連の 1 と 0 として表すことができます。
たとえば、0 は00000000
(8 ビット整数) として表され、多くの場合、127 は として表され01111111
ます。1 を 127 に加算すると、ビットが「反転」して にスワップされます10000000
が、標準的な 2 の補数表現では、これは実際には -128 を表すために使用されます。これにより、値が「オーバーフロー」します。
符号なしの数値でも同じことが起こります: 255 ( 11111111
) プラス 1 は になり100000000
ますが、「ビット」は 8 つしかないため00000000
、これは最終的に 0 になります。
これを回避するには、正しい整数サイズの適切な範囲チェックを行うか、適切な例外処理を行う言語を使用します。
オーバーフローは、算術演算の結果が演算のデータ型に収まらない場合です。結果 (256) がバイトの 8 ビットに収まらないため、255 + 1 を追加すると、バイトサイズの符号なし整数でオーバーフローが発生する可能性があります。
浮動小数点演算の結果が大きすぎて浮動小数点データ型の指数または仮数で表すことができない場合、浮動小数点数でオーバーフローが発生する可能性があります。
浮動小数点演算の結果が小さすぎて、指定された浮動小数点データ型で表すことができない場合、浮動小数点型でアンダーフローが発生することもあります。たとえば、浮動小数点データ型が -100 ~ +100 の範囲の指数を処理できる場合、値を -80 の指数で 2 乗すると、結果の指数は -160 付近になり、これは収まりません。指定された浮動小数点データ型。
コード内のオーバーフローとアンダーフローはサイレント キラーになる可能性があるため、注意する必要があります。コードは誤った結果を生成しますが、エラーを通知しない可能性があります。
オーバーフローを安全に無視できるかどうかは、プログラムの性質に大きく依存します。3D データからの画面ピクセルのレンダリングは、たとえば財務計算よりも数値エラーに対する許容度がはるかに高くなります。
オーバーフロー チェックは、多くの場合、既定のコンパイラ設定でオフになっています。なんで?各操作の後にオーバーフローをチェックする追加のコードには時間とスペースが必要なため、コードの実行時のパフォーマンスが低下する可能性があります。
少なくとも、オーバーフロー チェックを有効にしてコードを開発およびテストしてください。
演算によって整数値が最大値を超えると、整数オーバーフロー エラーが発生します。
たとえば、最大値が 100000 で、現在の値が 99999 の場合、2 を追加すると「オーバーフロー」になります。
データは不注意で変更または失われる可能性があり、より大きな整数型 (ほとんどの言語で long int を参照) または数字の長い文字列を非常に大きな整数に変換するスキームを使用して回避できるため、整数オーバーフローに注意する必要があります。
私は、これまでの他のすべての回答に少し反抗的になりたいと思います. 質問には言語に依存しないタグが付けられており、膨大な数の言語で整数がオーバーフローすることは決してないため、私の皮肉な答えは次のとおりです。
整数オーバーフロー エラーとは何ですか?
コンピューティングの暗黒時代からの時代遅れのアーティファクト。
なぜ私はそれを気にするのですか?
あなたはそうしない。
どうすれば回避できますか?
整数がオーバーフローしない最新のプログラミング言語を使用します。(Lisp、Scheme、Smalltalk、Self、Ruby、Newspeak、Ioke、Haskell、お好きなものをお選びください ...)
ウィキペディアから:
コンピューター プログラミングでは、算術演算で使用可能な記憶領域内で表現できるよりも大きな数値を作成しようとすると、整数オーバーフローが発生します。たとえば、表現できる最大値に 1 を加算すると、整数オーバーフローが構成されます。このような場合の最も一般的な結果は、結果の表現可能な最下位ビットが格納されることです (結果はラップされます)。
プログラムに適切なデータ型を選択する場合は特に注意する必要があります。そうしないと、非常に微妙なバグが発生する可能性があります。
http://www.first.org/conference/2006/papers/seacord-robert-slides.pdfから:
整数オーバーフローは、整数が最大値を超えて増加したり、最小値を超えて減少したりすると発生します。オーバーフローは、署名されている場合と署名されていない場合があります。
PS: PDF には、オーバーフローやその他の整数エラー状態に関する詳細な説明と、それらに対処/回避する方法が記載されています。
これは、使用されるバイト数が原因で整数の内部構造がサポートできる値よりも大きい値に整数を使用しようとすると発生します。たとえば、最大整数サイズが 2,147,483,647 で、3,000,000,000 を格納しようとすると、整数オーバーフロー エラーが発生します。