哪些语言将IEEE 754陷阱暴露给开发人员?

时间:2009-03-30 21:19:04

标签: floating-point ieee-754 floating-point-exceptions

我想把这些陷阱用于教育目的。

数值计算中的默认行为的一个常见问题是我们“错过”出现在错误操作中的Nan(或+ -inf)。默认行为是通过计算传播,但是某些操作(比如比较)会破坏链并松开Nan,并且其余的处理继续进行,而不会在算法的先前步骤中确认奇点。

有时我们有办法对这种事件做出反应:延长一个功能(“0/0 = 12在我的情况下”),或者在时域模拟中抛弃一步并尝试其他设置(如预测器) ,步长或其他)。

所以这是我的问题:您是否知道将IEEE754陷阱暴露给开发人员的语言?我不喜欢乱用ASM。

4 个答案:

答案 0 :(得分:3)

据我所知,在C和C ++中有两种浮点异常处理选择:

首先,如果禁用/屏蔽浮点异常(大多数环境默认情况下都这样做),您可以通过调用fetestexcept来查看是否发生了任何浮点异常。 fetestexcept在Visual C ++中不可用,但您可以轻松地窃取MinGW Runtime的实现。 (它在公共领域。)一旦异常被标记,它就不会被清除,直到你调用feclearexcept,所以你可以在一系列计算结束时调用fetestexcept,看看是否有任何异常引发异常。这并没有为您提供所要求的陷阱,但它确实让您测试是否发生了NaN或+/- inf等问题并根据需要做出反应。

其次,您可以通过在Linux中调用feenableexcept或在Windows中调用_controlfp来启用/取消屏蔽浮点异常。操作系统如何处理处理器生成的浮点异常取决于您的操作系统。

  • 在Linux中,操作系统发送SIGFPE信号,因此您可以安装一个信号处理程序来捕获它并设置一个标志,告诉您的例程做出适当的反应。
  • 在Windows中,操作系统调用结构化异常处理将处理器异常转换为语言异常,您可以使用C中的__try / __catch块或try / {{ 1}}在C ++中阻止。
  • 更新:对于Mac OS X,如this answer中所述,您应该能够使用catch中的_MM_SET_EXCEPTION_MASK启用/取消屏蔽例外,并且只要您使用默认编译器选项(即,不禁用SSE),您应该能够使用SIGFPE捕获异常。

(如果你很好奇的话,我在this blog posting的C和C ++中写了更多关于这个和其他浮点问题。)

答案 1 :(得分:0)

C和可能从C ++或python派生的大多数语言(虽然可能是间接访问)。期望低级语言能够获得这样的支持是合理的。

请参阅http://www.math.utah.edu/~beebe/software/ieee/#c-notes,其中有许多关于使用IEEE 754号码的脚本和注释。特别是of1.c处理浮点异常。最后,来自源http://grouper.ieee.org/groups/754/reading.html,其中包含大量有用的信息。

答案 2 :(得分:0)

我不确定标准是什么,但我可以告诉你我从经验中看到的内容,因为它可能有用。我用C ++编码,而NaN有时是我最糟糕的噩梦。它们默默地出现并通过计算一直传播到最后,直到我只有无用的输出。我经常不得不创建额外的代码来专门检测导致NaN的情况。我正在使用Visual C ++ 2008,所以我希望它以这种方式遵循IEEE标准。

答案 3 :(得分:0)

Maple的编程语言有一个尊重IEEE-754的数字模型,如果你愿意,你可以设置自己的陷阱处理程序。以下是一些链接:

Maple的一个不常见的属性是默认浮点数是十进制(非二进制)和任意精度。如果要处理64位二进制浮点数,请将它们包装在HFloat中。例如,0.2精确地表示十进制数,而HFloat(0.2)表示通过将0.2分配给C中的双精度得到的相同数字。例如,通过运行可以明显看出

a := HFloat(0.2);
b := 0.2;
evalf[20](a - b);

这使用20位十进制数字算法计算ab之间的差异,结果为0.11E-16