float ==和!=的情况不是直接对立的

时间:2016-07-08 15:39:04

标签: c ieee-754 comparison-operators

https://github.com/numpy/numpy/issues/6428中,错误的根本原因似乎是simd.inc.src:543,编译器会将!(tmp == 0.)优化为tmp != 0.

A comment说这些“不完全相同”。但没有指明任何细节。 NaNs被进一步提及,但测试显示NaN与预期方式的0.比较。

==!=可以返回true / false的情况是什么?

或差异在另一个字段 - 例如返回具有相同真值但是作为整数不同的值(但测试显示情况似乎并非如此)

2 个答案:

答案 0 :(得分:7)

  

评论说这些“不完全相同”。但没有指明任何细节。 NaNs被进一步提及,但测试表明NaN与预期的方式相比为0.

     

==和!=都可以返回true / false的情况是什么?

标准说:

  

<defs> <style type="text/css"> @font-face { font-family: 'Gunny Rewritten'; src: url('GunnyRewritten.woff'); } </style> </defs> (等于)和==(不等于)运算符类似于关系运算符,除了它们的优先级较低。 [...] 对于任何一对操作数,其中一个关系是正确的。

(C2011,6.5.9 / 3;重点补充)

因此,对于作为这些运算符的操作数共同允许的任何表达式X和Y,!=必须评估与(X) != (Y)相同的结果。如果在实践中发现它们不这样做,则产生该结果的编译器在这方面是不符合的。如果该不符合是意外的,那么它就构成了编译器中的错误。

此外,我观察到6.5.9 / 3同样适用于任何其他操作数的NaN,无穷大和次正规。由于不同的原因,NaNs对于这些运算符是特殊的:NaNs与所有操作数不相等,包括它们自己(假设IEEE语义)。

答案 1 :(得分:0)

来自链接帖子:

  

charris于2015年10月9日发表评论

     

我猜测!(tmp == 0.)已经优化为tmp != 0.,这不是一回事。

OP的评论:

  

作者说这是一个猜测,但他们非常肯定,!(tmp==0.)tmp!=0.并不等同,并表示好像是常识

我们如何调和这两个?

显然,它们逻辑等效。但实施方面,他们可能不是。编译器可能会将!(a == b)实现为测试a == b,然后进行否定。或者,它可以优化表达式,并直接测试a != b。在这两种情况下,结果汇编代码会有所不同。应该(必须)实现相同的结果,但执行时间可能不同。

“不完全相同的事情”只是承认!(a == b)a != b实际上是不同的字符组合,并且编译器可能会在技术上做出与它们不同的事情,这必须产生相同的结果。如果观察到不同的结果,则编译器中可能存在错误。