算術オーバーフローとは? わかりやすく解説

Weblio 辞書 > 辞書・百科事典 > ウィキペディア小見出し辞書 > 算術オーバーフローの意味・解説 

算術オーバーフロー

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/04/07 17:16 UTC 版)

算術オーバーフロー(さんじゅつオーバーフロー、: arithmetic overflow)あるいは単にオーバーフローは、デジタルコンピュータにおいて、演算結果がレジスタの表せる範囲や記憶装置上の格納域に記録できる範囲を超えてしまう現象、またはその結果レジスタ等に格納される値を意味する。オーバーフローは、本来演算結果を格納する場所とは違う場所に格納される場合がある。溢れあふれ)とも言う。

符号無し表現の加減算では、最上位桁より上の桁(存在しない桁)への繰り上がり(キャリー)や、おなじく存在しない桁からの繰り下がり(ボロー)が起きることが溢れである。フラグに保存され、キャリーフラグという名が付けられていることが多い。

加算器2の補数を使って減算を行っていて、加算器のキャリー入出力をそのままとしている場合、繰り下がり(ボロー)のなかった場合にフラグが立ち、繰り下がりがあった場合にはフラグが立たない、というロジックになる(6502POWERARMPICなど)。加算器#減算器も参照。

符号付き表現の、特に2の補数表現では、加減算のビット操作は符号無し表現のそれと全く同じであるが、最上位桁より上の桁との繰り上がりや繰り下がりではなく、最上位桁への繰り上がりや繰り下がりが溢れであることがある。最上位桁への繰り上がりや繰り下がりと同時に最上位桁より上の桁への繰り上がりや繰り下がりがあったら溢れではない。これのフラグはオーバーフローフラグという名が付けられていることが多い。

3ビットで+1を繰り返した場合でそれぞれの例を示す。

  • 0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 →(X)→ 0 ...
  • 0 → 1 → 2 → 3 →(Y)→ -4 → -3 → -2 → -1 →(YX)→ 0 ...

(X)と(YX)で最上位桁より上の桁への繰り上がりが起きている。(Y)と(YX)では最上位桁への繰り上がりが起きている。

浮動小数点数では、演算の結果、指数部が最大より大きくなった場合がオーバーフローで、結果が±(正または負の無限大、+INFあるいは-INF)になる。

オーバーフローの処理方法

オーバーフローの処理方法はいくつかある。

設計時の配慮
正しいデータ型(大きさと符号の有無)を選択する。
発生を未然に防ぐ
演算を注意深く並べ、必要に応じてオペランドを事前チェックすることによって、演算結果がオーバフローすることを防止する。
発生時の処理
オーバフロー発生時にその場で処理をする。例えば、2バイトの数値を1バイト毎の加算で加算する場合、まず下の桁(バイト)を加算して次に上の桁を加算する。このとき下の桁の加算でキャリーが発生した場合、上の桁の加算にキャリーのぶんも加算しなければならない。CPUには一般にそのような場合を検出する方法があり(ステータスレジスタ参照)、レジスタより大きな数の演算をサポートできるようになっている。例えば、Intel 8086の場合、オーバーフロー検知用のINTO 命令英語版を実行することでオーバーフローフラグをチェックし、セットされている場合には、オーバーフロー例外を発生する[1]
伝播
格納できる範囲を超えた値の場合、オーバーフローであることを示す特別な値を格納しておき、その後の演算に伝播させていく。長い計算の最後に値をチェックすればオーバフローが発生したことがわかるので、このような扱い方が便利な場合もある。特にFPUによる浮動小数点数の演算でよく使われる。
無視
最もよくある手法。しかし、結果が不正になるだけでなく、セキュリティホールの原因となることもある。

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]

DelphiC++Builderでは、浮動小数点演算でオーバーフローが発生した場合、System.SysUtils.EOverflowをスローする[18]。ただし、ARMアーキテクチャは浮動小数点例外をサポートしないため、すべての浮動小数点例外がマスクされている[19]。整数演算でオーバーフローが発生した場合、System.SysUtils.EIntOverflowをスローするが、プロジェクトのオーバーフローチェックが有効になっている必要がある[20]

その他

  • 1996年にあったアリアン5の事故は、オーバーフローを適切に扱っていなかったことが原因である[21]
  • 電卓の画面は一般的に十進数で表示されるが、電卓でも計算の結果オーバーフローが発生する場合がある(8桁電卓の99999999+1など)。これについての詳細は電卓#エラー表示についてを参照。

脚注

  1. ^ 田辺皓正編著『マイクロコンピュータシリーズ15 8086マイクロコンピュータ』丸善株式会社、1983年4月30日、83頁。 
  2. ^ MSC15-C. 未定義の動作に依存しない
  3. ^ Tell Programmers About Signed Integer Overflow Behavior
  4. ^ INT30-C. 符号無し整数の演算結果がラップアラウンドしないようにする
  5. ^ checked および unchecked ステートメント - オーバーフローチェック コンテキストを制御します - C# | Microsoft Learn
  6. ^ Math.Abs Method (System) | Microsoft Learn
  7. ^ SIGTERM, SIGSEGV, SIGINT, SIGILL, SIGABRT, SIGFPE - cppreference.com
  8. ^ <signal.h> - IEEE Std 1003.1-2017
  9. ^ signal(C RTL) - RAD Studio
  10. ^ _fpreset | Microsoft Learn
  11. ^ SIG35-C. シグナルハンドラ SIGSEGV、SIGILL、SIGFPE から復帰しない
  12. ^ FLP03-C. 浮動小数点エラーを検知して処理する
  13. ^ fetestexcept - cpprefjp C++日本語リファレンス
  14. ^ FE_OVERFLOW - cpprefjp C++日本語リファレンス
  15. ^ Structured Exception Handling - Win32 apps | Microsoft Learn
  16. ^ _controlfp_s | Microsoft Learn
  17. ^ Top Issues for Windows Titles - Win32 apps | Microsoft Learn
  18. ^ 浮動小数点例外 - RAD Studio
  19. ^ 浮動小数点演算について - RAD Studio
  20. ^ System.SysUtils.EIntOverflow - RAD Studio API Documentation
  21. ^ 失敗百選-アリアン5型ロケット爆発事故

関連項目


算術オーバーフロー

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/11/14 00:47 UTC 版)

クラスターミッション」の記事における「算術オーバーフロー」の解説

事故原因の調査加わったJean-Jacques Levyによると、問題引き起こしたAdaソースコードは以下のようなものであった。 L_M_BV_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BV) * G_M_INFO_DERIVE(T_ALG.E_BV));if L_M_BV_32 > 32767 then P_M_DERIVE(T_ALG.E_BV) := 16#7FFF#;elsif L_M_BV_32 < -32768 then P_M_DERIVE(T_ALG.E_BV) := 16#8000#;else P_M_DERIVE(T_ALG.E_BV) := UC_16S_EN_16NS(TDB.T_ENTIER_16S(L_M_BV_32));end if;P_M_DERIVE(T_ALG.E_BH) := UC_16S_EN_16NS (TDB.T_ENTIER_16S ((1.0/C_M_LSB_BH) * G_M_INFO_DERIVE(T_ALG.E_BH))); 最終行(ここでは2行となっている)がオーバーフローの原因となり、ここで64ビットから16ビットへの変換は保護されていなかった。正しいコードは以下のようになる。 L_M_BV_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BV) * G_M_INFO_DERIVE(T_ALG.E_BV));if L_M_BV_32 > 32767 then P_M_DERIVE(T_ALG.E_BV) := 16#7FFF#;elsif L_M_BV_32 < -32768 then P_M_DERIVE(T_ALG.E_BV) := 16#8000#;else P_M_DERIVE(T_ALG.E_BV) := UC_16S_EN_16NS(TDB.T_ENTIER_16S(L_M_BV_32));end if;L_M_BH_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BH) * G_M_INFO_DERIVE(T_ALG.E_BH));if L_M_BH_32 > 32767 then P_M_DERIVE(T_ALG.E_BH) := 16#7FFF#;elsif L_M_BH_32 < -32768 then P_M_DERIVE(T_ALG.E_BH) := 16#8000#;else P_M_DERIVE(T_ALG.E_BH) := UC_16S_EN_16NS(TDB.T_ENTIER_16S(L_M_BH_32));end if; 言い換えると、垂直方向の計算(E_BV)に既に実装されていたものと同じオーバーフローチェック機構平方向の計算(E_BH)にも実装されるべきであった

※この「算術オーバーフロー」の解説は、「クラスターミッション」の解説の一部です。
「算術オーバーフロー」を含む「クラスターミッション」の記事については、「クラスターミッション」の概要を参照ください。

ウィキペディア小見出し辞書の「算術オーバーフロー」の項目はプログラムで機械的に意味や本文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。 お問い合わせ


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「算術オーバーフロー」の関連用語

算術オーバーフローのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



算術オーバーフローのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアの算術オーバーフロー (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
ウィキペディアウィキペディア
Text is available under GNU Free Documentation License (GFDL).
Weblio辞書に掲載されている「ウィキペディア小見出し辞書」の記事は、Wikipediaのクラスターミッション (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。

©2025 GRAS Group, Inc.RSS