Float.NaN == Float.NaN

为什么这种比较会让我“假”? 我查看了源代码并将Float.NaN定义为

/** * A constant holding a Not-a-Number (NaN) value of type * float. It is equivalent to the value returned by * Float.intBitsToFloat(0x7fc00000). */ public static final float NaN = 0.0f / 0.0f; 

编辑:令人惊讶的是,如果我这样做:

 System.out.println("FC " + (Float.compare(Float.NaN, Float.NaN))); 

它给了我0 。 所以Float.compare()确实认为NaN等于它自己!

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

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

 def isNan(val): return val != val 

使用Float.isNaN检查NaN值。

我需要说的是: 维基百科关于NaN 。

它写得很清楚。 有趣的是,通用标准的浮点NaN以这种方式表示NaN:

s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx

s是符号(负数或正数),1是指数,x被视为有效负载。

查看有效载荷时,NaN与NaN不相等,并且很少有机会将这些有效载荷信息作为开发人员(例如复数)。

另一件事是,在标准中他们有信号和相当NaN。 信号NaN(sNaN)意味着NaN应该像exception一样引发反应。 它应该用来大声说出你的等式中有问题。 安静的NaN(qNaN)是一个静默传递的NaN。

创建信号的sNaN被转换为qNaN,以便在后续操作中不再产生任何信号。 记住一些系统将i ^ 0 = 1定义为NaN ^ 0 = 1的常数为真。 因此,有些人用NaN计算。

所以最后我会用这个:qNaN!= sNaN但是这是内部的,对用户来说是不可观察的(你无法检查)。 混合沿着支付和标志(是的,你可以有负和正NaN),在我看来,总是返回NaN!= NaN看起来是一个更明智的选择,我终于学会欣赏 – >我永远不会抱怨或怀疑关于NaN的不平等再次。 赞美那些深思熟虑的人,给我们这么好的标准!

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