Behaviour of negative zero (-0.0) in comparison with positive zero (+0.0)

ε祈祈猫儿з 提交于 2019-11-27 03:22:47

问题


In my code,

float f = -0.0; // Negative 

and compared with negative zero

f == -0.0f

result will be true.

But

float f = 0.0; // Positive

and compared with negative zero

f == -0.0f

also, result will be true instead of false

Why in both cases result to be true?


Here is a MCVE to test it (live on coliru):

#include <iostream>

int main()
{
    float f = -0.0;

    std::cout<<"==== > " << f <<std::endl<<std::endl;

    if(f == -0.0f)
    {
        std::cout<<"true"<<std::endl;
    }
    else
    {
        std::cout<<"false"<<std::endl;
    }
}

Output:

==== > -0  // Here print negative zero

true

回答1:


Floating point arithmetic in C++ is often IEEE-754. This norm differs from the mathematical definition of the real number set.

This norm defines two different representations for the value zero: positive zero and negative zero. It is also defined that those two representations must compare equals, so by definition:

+0.0 == -0.0

As to why it is so, in its paper What Every Computer Scientist Should Know About Floating Point Arithmetic, David Goldberg, 1991-03 (linked in the IEEE-754 page on the IEEE website) writes:

In IEEE arithmetic, it is natural to define log 0 = -∞ and log x to be a NaN when x < 0. Suppose that x represents a small negative number that has underflowed to zero. Thanks to signed zero, x will be negative, so log can return a NaN. However, if there were no signed zero, the log function could not distinguish an underflowed negative number from 0, and would therefore have to return -∞.




回答2:


That's because the signed negative zero must compare true with zero: i.e. -0.0 == 0.0, -0f == 0f, and -0l == 0l.

It's a requirement of any floating point scheme supported by a C++ compiler.

(Note that most platforms these days use IEEE754 floating point, and this behaviour is explicitly documented in that specification.)




回答3:


C++11 introduced functions like std::signbit() which can detect signed zeros, and std::copysign() which can copy the sign bit between floating point values, if the implementation supports signed zero (e.g. due to using IEEE floating point). That sort of thing aside, I'm unaware of any references in a C++ standard that even mention signed zeros, let alone what should be the result of comparing them

The C++ standards also do not stipulate any floating point representation - that is implementation-defined.

Although not definitive, these observations suggest that support of signed zeros, or the result of comparing them, would be determined by what floating point representation the implementation (aka compiler) supports.

IEEE-754 is the most common (albeit not the only) floating point representation used by modern implementations (i.e. compilers). The current (published in 2008) version of IEEE-758 "IEEE Standard for Floating -Point Arithmetic" Section 5.11, second paragraph, says (bold emphasise mine)

Four mutually exclusive relations are possible: less than, equal, greater than, and unordered. The last case arises when at least one operand is NaN. Every NaN shall compare unordered with everything, including itself. Comparisons shall ignore the sign of zero (so +0 = −0). Infinite operands of the same sign shall compare equal.




回答4:


Because 0.0f and -0.0f is same negative of a zero is zero



来源:https://stackoverflow.com/questions/45795397/behaviour-of-negative-zero-0-0-in-comparison-with-positive-zero-0-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!