算術オーバーフロー
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2024/04/07 17:16 UTC 版)
オーバーフローの処理方法
オーバーフローの処理方法はいくつかある。
- 設計時の配慮
- 正しいデータ型(大きさと符号の有無)を選択する。
- 発生を未然に防ぐ
- 演算を注意深く並べ、必要に応じてオペランドを事前チェックすることによって、演算結果がオーバフローすることを防止する。
- 発生時の処理
- オーバフロー発生時にその場で処理をする。例えば、2バイトの数値を1バイト毎の加算で加算する場合、まず下の桁(バイト)を加算して次に上の桁を加算する。このとき下の桁の加算でキャリーが発生した場合、上の桁の加算にキャリーのぶんも加算しなければならない。CPUには一般にそのような場合を検出する方法があり(ステータスレジスタ参照)、レジスタより大きな数の演算をサポートできるようになっている。例えば、Intel 8086の場合、オーバーフロー検知用のINTO 命令を実行することでオーバーフローフラグをチェックし、セットされている場合には、オーバーフロー例外を発生する[1]。
- 伝播
- 格納できる範囲を超えた値の場合、オーバーフローであることを示す特別な値を格納しておき、その後の演算に伝播させていく。長い計算の最後に値をチェックすればオーバフローが発生したことがわかるので、このような扱い方が便利な場合もある。特にFPUによる浮動小数点数の演算でよく使われる。
- 無視
- 最もよくある手法。しかし、結果が不正になるだけでなく、セキュリティホールの原因となることもある。
C言語およびC++では、符号付き整数のオーバーフローは未定義動作を引き起こす[2][3]。そのため、正しい作法にのっとったアプリケーションコードでは、オーバーフローの発生を未然に防がなければならない。符号無し整数はオーバーフローせず、ラップアラウンド(英: wraparound)と呼ばれる動作になることが規定されているが、メモリアドレスに関わるコードや、セキュリティ上重要な意味を持つコードではラップアラウンドも避けるべきとされている[4]。
- ^ 田辺皓正編著『マイクロコンピュータシリーズ15 8086マイクロコンピュータ』丸善株式会社、1983年4月30日、83頁。
- ^ MSC15-C. 未定義の動作に依存しない
- ^ Tell Programmers About Signed Integer Overflow Behavior
- ^ INT30-C. 符号無し整数の演算結果がラップアラウンドしないようにする
- ^ checked および unchecked ステートメント - オーバーフローチェック コンテキストを制御します - C# | Microsoft Learn
- ^ Math.Abs Method (System) | Microsoft Learn
- ^ SIGTERM, SIGSEGV, SIGINT, SIGILL, SIGABRT, SIGFPE - cppreference.com
- ^ <signal.h> - IEEE Std 1003.1-2017
- ^ signal(C RTL) - RAD Studio
- ^ _fpreset | Microsoft Learn
- ^ SIG35-C. シグナルハンドラ SIGSEGV、SIGILL、SIGFPE から復帰しない
- ^ FLP03-C. 浮動小数点エラーを検知して処理する
- ^ fetestexcept - cpprefjp C++日本語リファレンス
- ^ FE_OVERFLOW - cpprefjp C++日本語リファレンス
- ^ Structured Exception Handling - Win32 apps | Microsoft Learn
- ^ _controlfp_s | Microsoft Learn
- ^ Top Issues for Windows Titles - Win32 apps | Microsoft Learn
- ^ 浮動小数点例外 - RAD Studio
- ^ 浮動小数点演算について - RAD Studio
- ^ System.SysUtils.EIntOverflow - RAD Studio API Documentation
- ^ 失敗百選-アリアン5型ロケット爆発事故
- 1 算術オーバーフローとは
- 2 算術オーバーフローの概要
- 3 オーバーフローの処理方法
- 4 プログラミング環境と算術オーバーフロー
- 5 その他
- 算術オーバーフローのページへのリンク