什么是可能导致Python中的NaN的可能计算?

时间:2014-08-26 12:51:03

标签: python numpy floating-point nan

我一直在四处寻找,似乎有关于NaN在不同编程语言中的分散讨论,包括一些特定情况,但没有详尽或清楚。

在Python中,使用NumPy或SciPy时会产生NaN的最常见操作是什么?

1 个答案:

答案 0 :(得分:52)

如果您在没有使用浮点环境的情况下执行以下任何操作,您应该获得之前没有的NaN:

  • 0/0(在顶部和底部都有标记)
  • inf/inf(在顶部和底部都有标记)
  • inf - inf(-inf) + infinf + (-inf)(-inf) - (-inf)
  • 0 * infinf * 0(要么同时签署两个因素)
  • sqrt(x) 时,
  • x < 0fmod(x, y)y = 0无限时,
  • x;这里fmod是浮点余数。

机器算术的这些方面的规范参考是IEEE 754 specification。第7.1节描述了无效操作异常,它是在您即将获得NaN时引发的异常。 IEEE 754中的“例外”意味着与编程语言环境中的不同。

许多特殊功能实现记录了他们在尝试实现的功能的奇点时的行为。例如,请参阅atan2log的手册页。

你特别询问NumPy和SciPy。我不确定这是否仅仅是说“我在询问NumPy内部发生的机器算术”或“我在询问eig()和其他东西。”我假设前者,但这个答案的其余部分试图与NumPy中的高级函数进行模糊连接。基本规则是:如果函数的实现提交了上述罪行之一,则会获得NaN。

例如,对于fft,如果您的输入值大约为NaN或更大,则可能会获得1e1010,如果您的输入值在1e-1010或更小。但是,除了真正荒谬的缩放输入外,fft对你来说非常安全。

对于涉及矩阵数学的事情,如果您的数字很大,那么NaN可能会突然出现(通常通过inf - inf路线)。您的矩阵非常恶劣。关于如何通过数值线性代数搞定问题的完整讨论太长,不能归于一个答案。我建议在几个月的时间里翻阅一本数字线性代数书(Trefethen和Bau很受欢迎)。

在编写和调试“不应该”生成NaN的代码时,我发现有用的一件事就是告诉机器在发生NaN时陷阱。在GNU C中,我这样做:

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