IEEE754 中 inf==inf 的基本原理是啥

Posted

技术标签:

【中文标题】IEEE754 中 inf==inf 的基本原理是啥【英文标题】:What is the rationale for inf==inf in IEEE754IEEE754 中 inf==inf 的基本原理是什么 【发布时间】:2017-06-16 22:48:34 【问题描述】:

如果您有一个符合 IEEE754 的浮点实现,那么与 NaN 的任何比较都是 false,甚至是 NaN == NaN,但 +inf == +inftrue,为什么?

在我看来,说+inf == +inf 是假的会更有意义,原因:

自然数和有理数的个数,都是无限的,但又不相同。

如果你有 X=1e200Y=1e300(X 和 Y 都是 64 位双精度),那么 x==yfalse,但 x*1e200==y*1e200 是真的 true(两者都是+inf),这在数学上是不正确的。

对于NaN,已经需要特殊处理,其中X==Xfalse,因此实现+inf == +inf 返回false 不会有更多的实现复杂性。甚至可能更少,因为infNaN 我们是同一个“指数”。

我没有看到任何优势,或者任何需要+inf == +inf 的应用程序。无论如何,您都不应该将任何浮点值与== 进行比较。

X==Y 是通用的然后true,如果X-Y==0true,但inf-infNaN

编辑

正如 nwellnhof 已经写的:链接的问题:C IEEE-Floats inf equal inf,不一样,有一个问题“为什么语言实现是这样的?”,这里是问题“为什么标准是这样定义的?” . (而且这两个问题都来自同一个用户)

【问题讨论】:

C IEEE-Floats inf equal inf的可能重复 @LưuVĩnhPhúc 正如我在对链接问题的回答中指出的那样,我认为这不是重复的。 (为什么我的代码没有达到我的预期 vs. 为什么标准没有按照我的预期定义。) 在您的第一个原因中,您似乎将无限集的基数与扩展实线上的点混淆了。两者都恰巧被称为“无穷大”,但实际上彼此毫无关系。 (顺便说一句,自然数集的基数与有理数集的基数相同。) 【参考方案1】:

您可能需要询问 IEEE 754-1985 背后的主要架构师 William Kahan,但 this answer 对这个话题有所了解:

更重要的是,在 8087 算术中将 NaN 形式化时没有 isnan( ) 谓词;有必要为程序员提供一种方便有效的检测 NaN 值的方法,这种方法不依赖于提供类似 isnan() 的编程语言,这可能需要很多年。我将引用 Kahan 自己关于这个主题的文章:

如果没有办法摆脱 NaN,它们将与 CRAY 上的 Indefinites 一样无用;一旦遇到,最好停止计算,而不是无限期地继续下去,得出一个无限期的结论。这就是为什么对 NaN 的某些操作必须提供非 NaN 结果的原因。哪些操作? … 例外是 C 谓词“x == x”和“x!= x”,它们分别为 1 和 0对于每个无限或有限数 x [强调添加] 但如果 x 不是则相反一个数字( NaN );这些提供了NaN 和数字之间唯一简单的、无例外的区别 [强调] 在缺少 NaN 单词和谓词 IsNaN(x) 的语言中。

如果 +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 从纯数学的角度来看更正确。但 IMO,它并没有超过实际考虑。

自然数和有理数的[集合],都是无限的,但[具有]不相同的[基数]。

这与浮点计算没有太大关系。

如果你有 X=1e200 和 Y=1e300(X 和 Y 都是 64 位双精度数),那么 x==y 是假的,但 x*1e200==y*1e200 是真真(两者都是 + inf),这是数学上不正确的。

浮点数学在本质上是不正确的。您可以找到许多有限浮点数,XYZ,以及X != Y,其中X &lt;op&gt; Z == Y &lt;op&gt; Z

我没有看到任何优势,或者任何需要 +inf == +inf 的应用程序。无论如何,您都不应该将任何浮点值与 == 进行比较。

我也看不到需要+inf != +inf 的应用程序。

X==Y 为 [...] 为真,如果 X-Y==0 为真,但 inf-inf 为 NaN。

这实际上是+inf != +inf 可以解决的不一致问题。但这对我来说似乎是一个小细节。

【讨论】:

你冷还是用define is_nan(x) ( ((x)!=(x)) &amp;&amp; !((x)&lt;0) &amp;&amp; !((x)&gt;0) ),(+inf 还是会大于0,-inf 还是会小于0)即使+inf != +inf@ 或更短:define is_nan(x) ( !((x)&lt;=0) &amp;&amp; !((x)=&gt;0) ) @12431234123412341234123 查看我修改后的答案。 这是最好的办法,不用问卡汉教授。 IEEE FP 标准的早期草案对只有 INF 而没有符号的无穷大有“投影模式”的规定。在该模式下,INF 和有限数之间的比较返回“无序”,但 INF 与 INF 相比仍然相等。 Hewlett-Packard 的 Fraley & Walther 对 KCS (Kahan-Coonen-Stone) 提案提出了一个竞争性提案,该提案以不同方式处理溢出,详细信息可能在文档“安全处理溢出和下溢条件”中"我在网上找不到,也没有纸质版。 在一些early writing 中,Kahan 指出没有一致的方法来处理无穷大:一些 INF 实例实际上是无穷大(例如 1/0),而另一些则是溢出的结果(如在提问者的例子中)。我想说这是围绕零的同一个问题:要么是“干净”的零,要么是下溢的结果。 10,000ft 的问题是每个浮点数都可以精确地表示一个数学量,或者表示一个区间,而在执行给定的浮点运算时,通常我们不知道它是什么。

以上是关于IEEE754 中 inf==inf 的基本原理是啥的主要内容,如果未能解决你的问题,请参考以下文章

HaskellC++无穷量的表示

浮点数剖析

是否总是可以将`int`转换为`float`

考前自学系列·计算机组成原理·IEEE 754 单精度浮点数和真值之间的转化

(计算机组成原理)第二章数据的表示和运算-第三节2:IEEE754标准

计算机组成原理练习题——数据格式与IEEE754格式