【问题标题】:Behaviour of negative zero (-0.0) in comparison with positive zero (+0.0)与正零 (+0.0) 相比,负零 (-0.0) 的行为
【发布时间】:2017-08-21 10:58:52
【问题描述】:

在我的代码中,

float f = -0.0; // Negative 

并与负零

进行比较
f == -0.0f

结果将是true

但是

float f = 0.0; // Positive

并与负零

进行比较
f == -0.0f

另外,结果将是true 而不是false

为什么这两种情况的结果都是正确的?


这里是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;
    }
}

输出:

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

true

【问题讨论】:

标签: c++ floating-point ieee-754


【解决方案1】:

C++ 中的浮点运算通常是IEEE-754。这个范数不同于实数集的数学定义。

这个规范defines two different representations for the value zero: positive zero and negative zero。还定义了这两个表示必须比较等于,所以根据定义:

+0.0 == -0.0

至于为什么会这样,David Goldberg, 1991-03 在其论文What Every Computer Scientist Should Know About Floating Point Arithmetic(链接在 IEEE 网站上的 IEEE-754 页面)中写道:

在 IEEE 算术中,很自然地将 log 0 = -∞ 和 log x 定义为当 x

【讨论】:

  • 关于 IEEE-754 的进一步阅读:IEEE Standard 754 Floating Point Numbers,Steve Hollasch,2015 年 12 月 2 日。
  • log 参数有点可疑。 IEEE 754-2008 建议log(+0.0)log(-0.0) 都应返回负无穷大。 (参见第 9.2.1 节,“特殊值”。)
【解决方案2】:

C++11 引入了诸如 std::signbit() 之类的函数,它可以检测带符号的零,以及 std::copysign(),如果实现支持带符号的零(例如由于使用 IEEE 浮点),它可以在浮点值之间复制符号位。除了这类事情,我不知道 C++ 标准中的任何引用甚至提到了带符号的零,更不用说比较它们的结果了

C++ 标准也没有规定任何浮点表示 - 这是实现定义的。

虽然不是确定的,但这些观察表明,对有符号零的支持或比较它们的结果将取决于实现(也称为编译器)支持的浮点表示。

IEEE-754 是现代实现(即编译器)使用的最常见(尽管不是唯一)浮点表示。当前(2008 年发布)版本的 IEEE-758“IEEE 浮点算术标准”第 5.11 节第二段说(粗体强调我的)

可能有四种互斥关系:小于等于大于无序。最后一种情况出现在至少一个操作数是 NaN 时。每个 NaN 都应将 unordered 与所有内容进行比较,包括它自己。 比较应忽略零符号(因此+0 = -0)。相同符号的无限操作数应比较相等

【讨论】:

  • 严格来说,IEEE754 足够但不是必要std::signbit工作。
  • 是的,虽然 signbit() 是与其他一些明确指定的 IEEE754 功能一起引入的。无论如何,将相应地更新答案。
【解决方案3】:

这是因为带符号的负零必须true与零进行比较:即-0.0 == 0.0-0f == 0f-0l == 0l

这是 C++ 编译器支持的任何浮点方案的要求。

(请注意,如今大多数平台都使用 IEEE754 浮点,并且该规范中明确记录了这种行为。)

【讨论】:

    【解决方案4】:

    因为 0.0f 和 -0.0f 是相同的负数为零是零

    【讨论】:

    • 如果它们相同,它们将打印相同。它们是不相同的。但它们在== 中比较相等。
    • 问:“为什么 0.0f 和 -0.0f 相等?” ... 答:“因为”。这是一个糟糕的答案:-1.
    猜你喜欢
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 2018-02-13
    • 1970-01-01
    相关资源
    最近更新 更多