jck*_*jck 54 java floating-point comparison nan infinity
为什么无穷大比较遵循应用于NaN的逻辑?此代码打印出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
Run Code Online (Sandbox Code Playgroud)
但是,如果我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
Run Code Online (Sandbox Code Playgroud)
这似乎很危险.假设溢出产生无限值,我想更有可能的是,最终作为无穷大的两个变量在完美算术中实际上并不相等.
Pas*_*uoq 70
你的推理是Double.POSITIVE_INFINITY不应该与自己相等,因为它"很可能"是由于精度损失而获得的.
这条推理线适用于所有浮点数.由于操作不准确,可以获得任何有限值.这并没有促使IEEE 754标准化委员会定义==为总是对有限值进行评估,因此为什么无穷大会有所不同?
如定义,==对于理解它的作用的人(即,测试已经获得的浮点值,当然不是应该通过实际计算获得的值)是有用的.对于任何理解这一点的人,你需要理解它使用浮点,即使对于不涉及无穷大的计算也是Double.POSITIVE_INFINITY == Double.POSITIVE_INFINITY如此,如果只是为了测试浮点计算的浮点结果是Double.POSITIVE_INFINITY.
这就留下了为什么NaN能够承受特殊行为的问题,无穷大应遵循与有限值相同的一般原则.NaN与无穷大不同:IEEE 754标准的基本原则是值正好是它们,但是操作的结果可以相对于实际结果近似,在这种情况下,得到的浮点值根据舍入模式获得.
忘记1.0 / 0.0定义为+ inf 的瞬间,这在本次讨论中是一个烦恼.只考虑Double.POSITIVE_INFINITY作为诸如1.0e100 / 1.0e-300或之类的操作的结果Double.MAX_VALUE + Double.MAX_VALUE.对于这些操作,+ inf是实际结果的最接近的近似值,就像产生有限结果的操作一样.相比之下,NaN是您在操作无意义时获得的结果.让NaN特别表现是可以防御的,但inf只是所有值太大而无法表示的近似值.
在现实中,1.0 / 0.0也产生+ INF,但是这应该算是一个例外.将操作的结果定义为NaN同样一致,但在某些算法的实现中将其定义为+ inf更方便.卡汉的笔记第10页提供了一个例子.比大多数人希望的更多细节在文章"复杂的基本功能的分支削减,或许多无关的标志位".我还将解释在IEEE 754中存在与NaN标志分开的"除以零"标志,以识别用户可能想要特别地将除以零处理,尽管它没有被定义为产生NaN.
因为这是标准.Infinity表示大于或小于Double.MAX_VALUE/-Double.MAX_VALUE的数字.
NaN代表了一个没有意义的操作的结果.也就是说,操作不可能出现一个数字.
我猜测逻辑是一旦数字变得足够大(无穷大),并且由于浮点数的限制,向其添加数字不会改变结果,所以它的'喜欢'无穷大.
因此,如果你想要与真正的大数字进行比较,那么在某些时候你可能会说这两个大数字足够接近所有意图和目的.但是如果你想比较两个都不是数字的东西,你就无法比较它们,所以它是假的.至少你无法将它们作为基元进行比较.
为什么无限等于?因为它有效.
浮点运算旨在产生(相对)快速计算以保留错误.这个想法是你在漫长的计算过程中不检查溢出或其他废话; 你等到它完成了.这就是为什么NaNs以他们的方式传播的原因:一旦你获得了NaN,你可以做很少的事情就会让它消失.计算完成后,您可以查找NaN以检查是否出现了问题.
对于无穷大也是如此:如果存在溢出的可能性,不要做会丢弃无穷大的事情.
如果您想要变得缓慢而安全,IEEE-754具有安装陷阱处理程序的机制,以便在计算结果为NaN或无穷大时为您的代码提供回调.大多数情况下没有使用; 它通常太慢了,一旦代码被正确调试就毫无意义(不是那么容易:人们如何很好地掌握这些东西的博士学位).
| 归档时间: |
|
| 查看次数: |
4608 次 |
| 最近记录: |