我一直在四处寻找,似乎有关于NaN
在不同编程语言中的分散讨论,包括一些特定情况,但没有详尽或清楚。
在Python中,使用NumPy或SciPy时会产生NaN
的最常见操作是什么?
答案 0 :(得分:52)
如果您在没有使用浮点环境的情况下执行以下任何操作,您应该获得之前没有的NaN:
0/0
(在顶部和底部都有标记)inf/inf
(在顶部和底部都有标记)inf - inf
或(-inf) + inf
或inf + (-inf)
或(-inf) - (-inf)
0 * inf
和inf * 0
(要么同时签署两个因素)sqrt(x)
时,x < 0
当fmod(x, y)
或y = 0
无限时,x
;这里fmod
是浮点余数。机器算术的这些方面的规范参考是IEEE 754 specification。第7.1节描述了无效操作异常,它是在您即将获得NaN时引发的异常。 IEEE 754中的“例外”意味着与编程语言环境中的不同。
许多特殊功能实现记录了他们在尝试实现的功能的奇点时的行为。例如,请参阅atan2
和log
的手册页。
你特别询问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);