【问题标题】:Break on NaNs or infs打破 NaN 或 infs
【发布时间】:2010-12-21 00:44:11
【问题描述】:

通常很难找到 NaN 的起源,因为它可能发生在计算的任何步骤并自行传播。 那么当计算返回 NaN 或 inf 时,是否可以让 C++ 程序停止?在我看来,最好的方法是崩溃并显示一个很好的错误消息:

Foo: NaN encoutered at Foo.c:624

这样的事情可能吗?你有更好的解决方案吗?你如何调试 NaN 问题?

编辑:精度:我在 Linux 下使用 GCC。

【问题讨论】:

  • 有一种信号 NaN 会在硬件级别引发异常。也许你可以以某种方式捕获它,但我从来没有在靠近硬件的地方工作,所以没有确切的想法。但理论上它应该是可能的,因为 IEEE 754 明确包含了该功能。

标签: c++ exception floating-point numerical nan


【解决方案1】:

您无法以完全可移植的方式进行操作,但许多平台提供 C API,允许您访问浮点状态控制寄存器。

具体来说,您希望取消屏蔽溢出和无效浮点异常,这将导致处理器在程序中的算术产生 NaN 或无穷大结果时发出异常信号。

在您的 linux 系统上,这应该可以解决问题:

#include <fenv.h> 
...
feenableexcept(FE_INVALID | FE_OVERFLOW);

您可能想学习编写陷阱处理程序,以便在发出这些异常之一时打印诊断消息或以其他方式继续执行。

【讨论】:

  • 要捕获所有这样的异常,feenableexcept(FE_ALL_EXCEPT);
  • 致更多读者:在调试复杂的应用程序时,异常可能发生在您不感兴趣的地方。在这种情况下,您可以通过将 feenablexceptfedisableexcept 组合来仅隔离您关心的代码段
【解决方案2】:

是的!设置(可能或多或少可移植)您的 IEEE 754 兼容处理器,以在遇到 NaN 或无穷大时生成中断。

我在谷歌上搜索并找到了these slides,这是一个开始。第 5 页的幻灯片总结了您需要的所有信息。

【讨论】:

  • 链接已失效,但可在 webarchive here上找到
【解决方案3】:

我不是 C 专家,但我希望答案是否定的。

  1. 这将要求每个浮点计算都进行此检查。巨大的性能影响。
  2. NaN 和 Inf 并不邪恶。它们可能会在您的应用使用的某些库中合法使用,然后破坏它。

【讨论】:

  • 1.我相信当这种情况发生时 CPU 会升起一个标志。由于它是在硬件中完成的,因此不会对性能产生很大影响 2. 当然,但对于某些应用程序来说,它们是 :)
  • 关于 1.,它是在硬件中完成的,无需额外费用。 2. 是个问题,不过话说回来,简单地把默认的round-to-even舍入模式改为directed one来实现区间运算就有这个问题,所以也没什么新意了。
猜你喜欢
  • 2018-09-15
  • 2016-01-31
  • 2021-07-07
  • 2019-10-31
  • 2017-05-04
  • 2016-06-16
  • 1970-01-01
  • 1970-01-01
  • 2016-06-20
相关资源
最近更新 更多