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

[亡魂溺海] 提交于 2019-11-28 10:01:53

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 -∞.

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.)

Peter

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.

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

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