Float.NaN == Float.NaN

时间:2012-02-18 13:37:38

标签: java comparison floating-point nan

为什么这种比较会让我'假'?我查看了源代码,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 等于它自己!

3 个答案:

答案 0 :(得分:61)

使用Float.isNaN检查NaN值。

答案 1 :(得分:35)

因为Java实现了IEEE-754浮点标准,它保证与NaN的任何比较都将返回false(除了返回true的!=

这意味着,您无法以通常的方式检查浮点数是否为NaN,因此您可以将这两个数字重新解释为整数并进行比较或使用更明确的解决方案:

def isNan(val):
     return val != val

答案 2 :(得分:0)

我需要说的是: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看起来像一个更明智的选择,我终于学会欣赏 - &gt;我再也不会抱怨或怀疑NaN的不平等。赞美那些深思熟虑的人给我们这么好的标准!

顺便说一句:Java使用有效负载为0的正NaN(所有x都为零)。