Remove ads
ウィキペディアから
算術オーバーフロー(さんじゅつオーバーフロー、英: arithmetic overflow)あるいは単にオーバーフローは、デジタルコンピュータにおいて、演算結果がレジスタの表せる範囲や記憶装置上の格納域に記録できる範囲を超えてしまう現象、またはその結果レジスタ等に格納される値を意味する。オーバーフローは、本来演算結果を格納する場所とは違う場所に格納される場合がある。溢れ(あふれ)とも言う。
符号無し表現の加減算では、最上位桁より上の桁(存在しない桁)への繰り上がり(キャリー)や、おなじく存在しない桁からの繰り下がり(ボロー)が起きることが溢れである。フラグに保存され、キャリーフラグという名が付けられていることが多い。
加算器で2の補数を使って減算を行っていて、加算器のキャリー入出力をそのままとしている場合、繰り下がり(ボロー)のなかった場合にフラグが立ち、繰り下がりがあった場合にはフラグが立たない、というロジックになる(6502・POWER・ARM・PICなど)。加算器#減算器も参照。
符号付き表現の、特に2の補数表現では、加減算のビット操作は符号無し表現のそれと全く同じであるが、最上位桁より上の桁との繰り上がりや繰り下がりではなく、最上位桁への繰り上がりや繰り下がりが溢れであることがある。最上位桁への繰り上がりや繰り下がりと同時に最上位桁より上の桁への繰り上がりや繰り下がりがあったら溢れではない。これのフラグはオーバーフローフラグという名が付けられていることが多い。
3ビットで+1を繰り返した場合でそれぞれの例を示す。
(X)と(YX)で最上位桁より上の桁への繰り上がりが起きている。(Y)と(YX)では最上位桁への繰り上がりが起きている。
浮動小数点数では、演算の結果、指数部が最大より大きくなった場合がオーバーフローで、結果が±∞(正または負の無限大、+INF
あるいは-INF
)になる。
オーバーフローの処理方法はいくつかある。
C言語およびC++では、符号付き整数のオーバーフローは未定義動作を引き起こす[2][3]。そのため、正しい作法にのっとったアプリケーションコードでは、オーバーフローの発生を未然に防がなければならない。符号無し整数はオーバーフローせず、ラップアラウンド(英: wraparound)と呼ばれる動作になることが規定されているが、メモリアドレスに関わるコードや、セキュリティ上重要な意味を持つコードではラップアラウンドも避けるべきとされている[4]。
プログラミング言語や実行環境の中には、算術オーバーフローを検出したときに例外をスローするなど、エラーハンドリングを容易にしてくれるものもある。
C#ではchecked
キーワード(checked
ステートメントやchecked
演算子)を使うことで、整数演算によってオーバーフローが発生したときSystem.OverflowException
がスローされるようになる[5]。ただし浮動小数点演算の場合はスローされない。他にも、整数型T
の引数を受け取るSystem.Math.Abs()
メソッドのオーバーロードは、T.MinValue
に対してSystem.OverflowException
をスローする[6]。
JavaはC#のchecked
に相当する機能を直接持たない。ただし、Java 8でMath
クラスに追加されたExact
系メソッドを使うと、オーバーフローが発生したときにArithmeticException
がスローされる。
ISO C/C++では、SIGFPE
のシグナルがサポートされている[7]。シグナルハンドラーを設定すると、POSIXではオーバーフロー発生時にFPE_INTOVF
またはFPE_FLTOVF
のエラーコードを伴うシグナルが発生する[8]。C++BuilderではFPE_INTOVFLOW
またはFPE_OVERFLOW
となる[9]。Microsoft Visual C++では整数オーバーフローによるシグナルは発生せず、浮動小数点数オーバーフロー発生時に_FPE_OVERFLOW
のエラーコードを伴うシグナルが発生する[10]。ただし、SIGFPE
のシグナルハンドラーからは復帰するべきではなく、そのまま終了するべきとされている[11]。
C99およびC++11では、直前の演算によって浮動小数点例外が発生したかどうかをチェックできるテスト関数fetestexcept()
を標準化している[12][13]。オーバーフローを検出するにはテストビットとしてFE_OVERFLOW
を使用する[14]。
Microsoft Visual C++のランタイムライブラリは、デフォルトではすべての浮動小数点例外をマスクしているが、_controlfp_s()
関数などを使ってオーバーフローの浮動小数点例外を有効化すると、Microsoft Windows固有のエラー処理機構である構造化例外[15]をスローするようになる[16]。なお、制御ワードの設定はスレッドごとに管理されているため、浮動小数点例外を有効化する場合はスレッドごとに設定が必要となる[17]。
DelphiやC++Builderでは、浮動小数点演算でオーバーフローが発生した場合、System.SysUtils.EOverflow
をスローする[18]。ただし、ARMアーキテクチャは浮動小数点例外をサポートしないため、すべての浮動小数点例外がマスクされている[19]。整数演算でオーバーフローが発生した場合、System.SysUtils.EIntOverflow
をスローするが、プロジェクトのオーバーフローチェックが有効になっている必要がある[20]。
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.