2017-12-02 8 views
5

ゼロ除算除外例外に驚いています。どうすれば元に戻すことができますか?デルファイベルリン10.1ゼロ除算例外がありません

インストールごく最近のベルリン10.1、新しいプロジェクト、

procedure TForm1.Button1Click(Sender: TObject); 
var 
    a: Double; 
begin 
    a := 5/0;      // No exception 
    ShowMessage(a.ToString);  // -> 'INF' 
end; 
+1

私のベルリンに確認済みです。東京にもあるようです:https://community.embarcadero.com/answers/divide-by-zero-different-in-rad-studio-10-2 –

+6

@ジェリー:それは式が定数式であるからです。実行時には計算されません。例外を発生させるには、2つの数値(被除数、除数)の少なくとも1つが変数でなければなりません。 –

+2

素晴らしい!コンパイラは0で割り切る方法を知っています:) – Victoria

答えて

7
a := 5/0; 

表現5/0は、技術的な言語の用語で、constant expressionあります。

定数式は、発生するプログラムを実行せずにコンパイラが評価できる式です。定数式には数字が含まれます。文字列。真の定数;列挙型の値。特別な定数True、False、およびnil;これらの要素から演算子、型キャスト、およびコンストラクタを使用して排他的に作成された式です。

このように、この式はコンパイラによって評価され、実行時では評価されません。したがって、その評価はコンパイル時の規則によって決定され、ランタイム浮動小数点ユニット例外マスクの影響を受けることはありません。

これらのルールでは、正の値を0で割った値は、IEEE754の値である+INFに等しいことが示されています。式を変更して、少なくとも1つの引数が定数式でない場合は、実行時に評価され、ゼロ除算例外が発生します。

4

あなたは浮動小数点例外は数学の単位でSetExceptionMask機能を使用してトリガするかを制御することができます:http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Math.SetExceptionMask

例外が使用するすべての浮動小数点を無効にするには:

SetExceptionMask(exAllArithmeticExceptions); 

すべての浮動小数点例外の使用を有効にするには:

SetExceptionMask([]); 

また、コンパイル時に(式が定数なので)コンパイラは値を決定するので、SetExceptionMaskに渡される値に関係なく例外をトリガしません。あなたはもう少し複雑な例を必要とする例外をトリガするには、このような何か:

program test; 
uses Math; 
var 
    xx,yy: double; 
begin 
SetExceptionMask([]); 
xx := 1; 
yy := 0; 
halt(round(xx/yy)); 
end. 
+0

そして、ゼロ除算を有効にするには、次のようにします: 'SetExceptionMask(GetExceptionMask - [exZeroDivide]);'。 –

+3

少なくともこの答えの最初の部分は、質問に関係していません。 –

+3

@DavidHeffernan浮動小数点例外のトリガではないことについての議論では、SetExceptionMaskに言及することが適切であると思います。確かに、それはOPコードの理由ではなかったかもしれませんが、ここではコードがあまりに単純化され、実際のコードは変数を使用する可能性があります。 –

関連する問題