浮点数.NaN == 浮点数.NaN
Posted
技术标签:
【中文标题】浮点数.NaN == 浮点数.NaN【英文标题】:Float.NaN == Float.NaN 【发布时间】:2012-03-09 15:27:18 【问题描述】:为什么这个比较给了我“假”?我查看了源代码,Float.NaN 被定义为
/**
* A constant holding a Not-a-Number (NaN) value of type
* <code>float</code>. It is equivalent to the value returned by
* <code>Float.intBitsToFloat(0x7fc00000)</code>.
*/
public static final float NaN = 0.0f / 0.0f;
编辑:令人惊讶的是,如果我这样做:
System.out.println("FC " + (Float.compare(Float.NaN, Float.NaN)));
它给了我0
。所以Float.compare()
确实认为 NaN is 等于它自己!
【问题讨论】:
【参考方案1】:使用 Float.isNaN
检查 NaN 值。
【讨论】:
@Rolfツ 没什么可补充的,很简单。【参考方案2】:因为 Java 实现了 IEEE-754 浮点标准,该标准保证与 NaN
的任何比较都将返回 false(!=
除外,它返回 true)
这意味着,您无法以通常的方式检查浮点数是否为 NaN,因此您可以将两个数字重新解释为整数并进行比较,或者使用更聪明的解决方案:
def isNan(val):
return val != val
【讨论】:
!=
比较除外,它返回 true
。
您实际上可以通过这种方式测试 NaN!如果x==x
为假,则 x 为 NaN。
你也可以使用静态的Float.isNaN(float)
(Double 也有它的版本)。
我想知道原因是什么?我理解将 NaN 视为既不大于、等于也不小于其他任何值的基本原理,但 x==y
最明智的含义是“x 与 y 无法区分”,并且如果 x 和 y 恰好都是 NaN这种说法是正确的。我想不出任何明智的“问题”可以用 IEEE 指定的平等规则来回答。
@supercat 我相信 !(NaN == Nan) 的原因是因为 NaN 可以用来表示很多东西。例如,(3.0/0.0) == (1.0/0.0) 吗?这很难明确地说是,所以我认为这就是为什么他们不能平等比较。【参考方案3】:
我只需要说:Wikipedia About NaN。
写得很清楚。有趣的是,通用标准的浮点 NaN 是这样表示 NaN 的:
s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx
s 是符号(负或正),1 是指数,x 被认为是有效载荷。
查看负载时,NaN 不等于任何 NaN,作为开发人员,负载的这些信息很少会引起您的兴趣(例如复数)。
另一件事是,在标准中他们有信号和相当的 NaN。信号 NaN (sNaN) 表示应该引发异常反应的 NaN。它应该用来大声说你的方程式有问题。安静的 NaN (qNaN) 是静默传递的 NaN。
创建信号的 sNaN 被转换为 qNaN,以便在后续操作中不再产生任何信号。请记住,某些系统将 i^0 = 1 定义为 NaN^0 = 1 成立的常数。所以有些情况下人们用 NaN 进行计算。
所以最后我会选择这个:qNaN != sNaN 但这是内部的,用户无法观察到(你无法检查)。将付款和符号混合在一起(是的,您可以有负数和正数 NaN),在我看来,总是返回 NaN!= NaN 看起来是一个更明智的选择,我终于学会了欣赏 -> 我永远不会抱怨或怀疑再次讨论 NaN 的不等式。赞美那些考虑周到的人给我们这么好的标准!
顺便说一下:Java 使用负数为 0 的正 NaN(所有 x 都是零)。
【讨论】:
复数与有效载荷有什么关系? @MarkDickinson,***页面建议“使用 sNaN 作为更复杂对象的占位符,例如 […] 复数”以上是关于浮点数.NaN == 浮点数.NaN的主要内容,如果未能解决你的问题,请参考以下文章
ZeroDivisionError 整数异常,Nan 浮点数