当您有符合 IEEE754 标准的浮点实现时,与
NaN
的任何比较都是 false
,甚至是 NaN == NaN
,但是 +inf == +inf
是 true
,为什么?
从我的角度来看,说
+inf == +inf
是假的更有意义,原因:
自然数和实数的个数都是无穷大但不相同。
如果您有
X=1e200
和 Y=1e300
(X 和 Y 都是 64 位双精度数),那么 x==y
是 false
,但 x*1e200==y*1e200
是 true true
(两者都是 +inf),这是数学上不正确的。
对于
NaN
,已经需要进行特殊处理,其中X==X
是false
,因此实现+inf == +inf
返回false
不会有更多的实现复杂性。也许甚至更少,因为 inf
和 NaN
我们相同的“指数”。
我没有看到任何优势,或任何需要这样的应用程序
+inf == +inf
。无论如何,您都不应该将任何浮点值与 ==
进行比较。
X==Y
是通用的,那么 true
,如果 X-Y==0
是 true
,但是 inf-inf
是 NaN
。
编辑
正如nwellnhof allready所写:链接的问题:C IEEE-Floats inf equal inf,是不一样的,有一个问题“为什么语言实现是这样的?”,这是问题“为什么定义了标准这边走?”。 (两个问题都来自同一个用户)
您可能必须询问 IEEE 754-1985 背后的主要架构师 William Kahan,但是 这个答案 揭示了这个主题的一些亮点:
如果更重要的是,当 NaN 在 8087 算术中形式化时,还没有 isnan( ) 谓词;有必要为程序员提供一种方便而有效的方法来检测 NaN 值,这种方法不依赖于编程语言提供像 isnan() 这样的东西,这可能需要很多年。我将引用卡汉自己关于这个主题的文章:
如果没有办法摆脱 NaN,它们就会像 CRAY 上的不定式一样毫无用处;一旦遇到一个,最好停止计算,而不是无限期地继续计算以获得不确定的结论。这就是为什么对 NaN 的某些操作必须提供非 NaN 结果的原因。哪些操作? …例外是 C 谓词“ x == x ”和“ x != x ”,对于每个无限或有限数 x,它们分别为 1 和 0 [强调],但如果 x 不是数字 ( NaN ),则相反;在缺少 NaN 单词和谓词 IsNaN(x) 的语言中,这些提供了 NaN 和数字之间唯一简单且无异常的区别 [强调]。
+inf
不等于
+inf
,则 NaN 的
x != x
测试将不起作用,因为它也会捕获无穷大。早在 1985 年,C 程序员就可以这样写:
#define is_nan(x) ((x) != (x))
#define is_pos_inf(x) ((x) == 1.0/0.0)
#define is_neg_inf(x) ((x) == -1.0/0.0)
使用
inf != inf
,你需要类似的东西:
#define is_nan(x) (!((x) >= 0) && !((x) <= 0))
#define is_pos_inf(x) ((x) != (x) && (x) > 0.0)
#define is_neg_inf(x) ((x) != (x) && (x) < 0.0)
我可以理解你的观点,并且我同意从纯粹数学的角度来看,拥有
+inf != +inf
更正确。但在我看来,这并没有超过实际的考虑。
自然数和有理数的[集合]都是无限的,但[具有]不同的[基数]。这与浮点计算没有太大关系。
如果你有 X=1e200 和 Y=1e300 (两者,X 和 Y 都是 64 位双精度数),那么 x==y 为 false,但 x*1e200==y*1e200 为 true true (两者都是 +inf) ,这是数学上不正确的。浮点数学本质上是不正确的。您可以找到许多
有限浮点数,X
、
Y
、
Z
,以及
X != Y
,其中
X <op> Z == Y <op> Z
。
我没有看到任何优势,也没有看到任何需要 +inf == +inf 的应用程序。无论如何,您都不应该将任何浮点值与 == 进行比较。我也看不到需要
+inf != +inf
的应用程序。
X==Y 为 [...] true,如果 X-Y==0 为 true,但 inf-inf 为 NaN。这实际上是
+inf != +inf
可以解决的不一致问题。但这对我来说似乎只是一个小细节。