0 による除算エラー等の浮動小数点演算エラーは,次のようにして回避できます.
Math ユニットにある SetExceptionMask 関数を使用します.
この設定はそのプロセスだけで有効です.Set8087CW という関数もありますが,これも同じです.
システム全体に影響を与えることはできません.
このサンプルを起動して,演算エラーを無効にした後で,別の Delphi 製のプログラムで演算エラーが発生するコードを実行します.
演算エラーが発生することが確認できます.
メインフォームの OnDestroy イベントで元の状態に戻しておきます.
OnCreate もそうですが,OnCreate が実行される前に,いろいろな初期化作業が行われています.
実際に,OnCreate が発生した時点で,オブジェクト・インスペクタ等の設定は終了しています.
それと同じように,OnDestroy イベントの後にも,終了作業が行われます.
この時,演算エラーを無視したままの状態だと,予期しない結果が発生するかも知れません.
動作確認環境は以下です,他の環境での確認はしていません.あしからず.
Windows 7 U64(SP1) + Delphi 7 Pro (どこかの掲示板の発言風に言えば,DEL7P でしょうか ?)
Windows 7 U64(SP1) + Delphi XE Pro (どこかの掲示板の発言風に言えば,DELXEP でしょうか ?)

var SaveFPUMask : TFPUExceptionMask;
//============================================================================= // 0による除算エラーを発生させる // このサンプルの実行には,usesにMathが必要 //============================================================================= procedure TForm1.Button1Click(Sender: TObject); var A : Double; B : Double; C : Double; begin A := 100; B := 0;
//Windows 7 の環境下で,Delphi 6,7 で作成したEXEでも発生させるため処置 //何かしらの演算をすると発生する C := Round(A / B); end;
//============================================================================= // フォーム生成時の処理 // これがメインフォームなので,アプリ起動時ということになる //============================================================================= procedure TForm1.FormCreate(Sender: TObject); begin //現在の設定を退避 //SaveFPUMaskはTFPUExceptionMask型の変数 SaveFPUMask := Math.GetExceptionMask; end;
//============================================================================= // フォームの破棄の時の処理 // これがメインフォームなので,アプリ終了時ということになる //============================================================================= procedure TForm1.FormDestroy(Sender: TObject); begin //元の設定に戻す Math.SetExceptionMask(SaveFPUMask); end;
//============================================================================= // 浮動小数点演算エラーの時の処理を変更 //============================================================================= procedure TForm1.CheckBox1Click(Sender: TObject); begin if CheckBox1.Checked then begin //全ての浮動小数点演算の例外を無視する Math.SetExceptionMask([exInvalidOp, exDenormalized, exZeroDivide, exOverflow, exUnderflow, exPrecision]); end else begin //元の設定に戻す Math.SetExceptionMask(SaveFPUMask); end; end;
参考リンク
[System.Math.SetExceptionMask]
http://docwiki.embarcadero.com/Libraries/XE4/ja/System.Math.SetExceptionMask
[System.Math.TFPUException]
http://docwiki.embarcadero.com/Libraries/XE3/ja/System.Math.TFPUException
[System.Set8087CW]
http://docwiki.embarcadero.com/Libraries/XE2/ja/System.Set8087CW
[浮動小数点数の制御ルーチン]
http://docwiki.embarcadero.com/RADStudio/XE4/ja/%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0%E3%81%AE%E5%88%B6%E5%BE%A1%E3%83%AB%E3%83%BC%E3%83%81%E3%83%B3
[942_TEmbeddedWB コンポーネント]
http://mrxray.on.coocan.jp/Delphi/plSamples/942_TEmbeddedWB.htm
|