当前位置: 首页 > 知识库问答 >
问题:

为什么浮点无穷大,不像NAN,是相等的?

欧阳睿范
2023-03-14

为什么无穷大比较不遵循应用于NANS的逻辑?此代码打印出false三次:

double a = Double.NaN;
double b = Double.NaN;
System.out.println(a == b); // false
System.out.println(a < b); //  false
System.out.println(a > b); //  false

但是,如果将double.nan更改为double.positive_infinity,则等于取true,大于和小于比较取false:

double a = Double.POSITIVE_INFINITY;
double b = Double.POSITIVE_INFINITY;
System.out.println(a == b); // true
System.out.println(a < b); //  false
System.out.println(a > b); //  false

这看起来很危险。假设无穷大的值是由溢出产生的,我想更有可能的是,两个最终为无穷大的变量在完美算术中实际上并不相等。

共有1个答案

单于帅
2023-03-14

您的推理是double.positive_infinity不应该等于它本身,因为它“很可能”是由于丢失了准确性而获得的。

这条推理线适用于所有浮点。任何有限值都可以作为一个不精确操作的结果得到。这并没有促使IEEE 754标准化委员会将==定义为对有限值总是计算为false,那么为什么无穷大值要不同呢?

正如定义的那样,==对于了解它的作用(即测试已经获得的浮点值,而不是应该通过实际计算获得的值)的人非常有用。对于任何了解这一点的人,并且即使在不涉及无穷大的计算中使用浮点,您也需要了解这一点,将double.positive_infinity==double.positive_infinity求值为true是很方便的,这只是为了测试浮点计算的浮点结果是否为double.positive_infinity

这就留下了一个问题:为什么NaN能够承受特殊的行为,而无穷大应该遵循与有限值相同的一般原则。NaN与无穷大不同:IEEE 754标准的基本原则是,值就是它们本身,但运算的结果可以相对于实际结果近似,在这种情况下,结果浮点值是根据舍入模式获得的。

暂时忘记1.0/0.0被定义为+INF,这在本讨论中是一个麻烦。暂时把double.positive_infinity看作是1.0E100/1.0E-300double.max_value+double.max_value等操作的结果。对于这些操作,+INF是真实结果的最接近近似,就像对于产生有限结果的操作一样。相比之下,NaN是当操作没有意义时得到的结果。让NaN有特殊的行为是可以辩护的,但是inf只是所有太大而无法表示的值的近似值。

实际上,1.0/0.0也生成+INF,但这应该被视为一个例外。将该操作的结果定义为NaN将是同样连贯的,但将其定义为+INF在某些算法的实现中更为方便。Kahan的笔记第10页提供了一个例子。更多的细节超过了大多数人的愿望,在文章“分支削减为复杂的基本函数,或许多Ado关于nother's Sign bit”。我还将IEEE 754中与NaN标志分开的“除以零”标志的存在解释为用户可能希望特别处理除以零,尽管它没有定义为生成NaN。

 类似资料:
  • 问题内容: 我们如何在代码中使用它们,什么会导致NaN(不是数字)? 问题答案: 如果您想了解有关Java中浮点数的更多信息,这可能是一个很好的参考。 正无穷大是一个正数,以至于无法正常表示。负无穷大是一个负数,以至于无法正常表示。NaN的意思是“不是数字”,它是由数学运算产生的,该数学运算不会产生数字,例如将0除以0。 在Java中,Double和Float类都具有代表三种情况的常量。它们是PO

  • 问题 你想创建或测试正无穷、负无穷或NaN(非数字)的浮点数。 解决方案 Python并没有特殊的语法来表示这些特殊的浮点值,但是可以使用 float() 来创建它们。比如: >>> a = float('inf') >>> b = float('-inf') >>> c = float('nan') >>> a inf >>> b -inf >>> c nan >>> 为了测试这些值的存在,使用

  • 众所周知,在比较浮点值时必须小心。通常,我们不使用,而是使用一些基于epsilon或ULP的相等性测试。 然而,我想知道,当使用时,是否存在任何情况? 看看这个简单的片段,哪些案例可以保证成功? 注意:我已经检查了这个和这个,但是它们不包括我的(所有)病例。 注2:似乎我必须添加一些附加信息,因此答案在实践中可能很有用:我想知道: C标准的内容 这是我在当前标准草案中发现的唯一相关声明: 浮点类型

  • 例如,它不是返回2,而是返回“11” 我正在从该API收集数据:https://www.hatchways.io/api/assessment/students obs(为了检索数据,我创建了一个服务:export class StudentsService{ String="https://www.hatchways.io/api/assessment/students"; 构造函数(私有htt

  • 由于某些原因,这部分不起作用: 我将错误“无法将«类ocid»id«数据optr000000003701000000000000»转换为类型编号。(错误-1700)” 你知道为什么会这样吗?我想这是因为它不想让我把浮点和整数结合起来。如果这是原因,为什么?我该如何修复它?如果这不是问题,你认为是什么? 谢谢!

  • 为什么Java中的以下代码 打印“无穷大”而不是未定义。这在数学上不是错的吗?