德尔福柏林10.1分部通过零例外失踪
我很惊讶没有得到除零例外。我如何恢复?德尔福柏林10.1分部通过零例外失踪
柏林10.1非常新安装,新的项目,
procedure TForm1.Button1Click(Sender: TObject); var
a: Double;
begin
a := 5/0; // No exception
ShowMessage(a.ToString); // -> 'INF'
end;
回答:
a := 5/0;
表达5/0
是,在技术语言来说,一个constant expression。
常量表达式是一种表达式,编译器可以在不执行它所在的程序的情况下对其进行评估。常量表达式包括数字;字符串;真常数;枚举类型的值;特殊常量True,False和零;以及由这些元素完全由操作符,类型转换和设置构造函数构建的表达式。
因为这样的表达式由编译器评估,而不是在运行时评估。所以它的评估是由编译时间规则决定的,不能受到运行时浮点单元异常掩码的影响。
这些规则规定正值除以零等于+INF
,这是一个特殊的IEEE754值。如果将表达式更改为至少有一个不是常量表达式的参数,那么将在运行时对其进行评估,并且将会引发零除异常。
回答:
可以使用数学单元的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.
以上是 德尔福柏林10.1分部通过零例外失踪 的全部内容, 来源链接: utcz.com/qa/257895.html