2

我有一个程序示例:

int main()
{
    double x;
    x=-0.000000;
    if(x<0)
    {
        printf("x is less");
    }
    else 
    {
        printf("x is greater");
    }
}

为什么控制在第一条语句中 - x is less 。什么是-0.000000?

4

3 回答 3

9

IEEE 754 定义了一个非常常用的标准浮点数。你可以在这里看到它的结构:

有限数,可以是基数 2(二进制)或基数 10(十进制)。每个有限数由三个整数描述:s = 符号(零或一),c = 有效数(或“系数”),q = 指数。有限数的数值是

  (−1)^s × c × bq

其中 b 是基数(2 或 10)。例如,如果符号为 1(表示负数),有效数字为 12345,指数为 -3,底数为 10,则数字的值为 -12.345。

双FP号

因此,如果分数为 0,符号为 0,则为 +0.0。
如果分数为 0,符号为 1,则为 -0.0。

这些数字具有相同的值,但它们在正/负检查中有所不同。这意味着,例如,如果:

x = +0.0;
y = -0.0;

然后你应该看到:

(x -y) == 0

但是,对于 x,OP 的代码将使用“x is greater”,而对于 y,它将使用“x is less”。

编辑: Artur回答Jeffrey Sax对这个答案的评论澄清x < 0了 OP 问题中的测试差异实际上是编译器优化,实际上对x < 0正负的测试0应该始终是false.

于 2013-11-12T06:35:19.537 回答
2

内森是对的,但有一个问题。通常大多数浮点/双精度操作由协处理器执行。然而,一些编译器试图变得聪明,而不是让协处理器进行比较(它将 -0.0 和 +0.0 视为 0.0)只是假设因为你的x变量有减号,这意味着它应该被视为负数并优化你的代码。

如果您能够看到汇编输出的样子 - 我敢打赌您只会看到调用:

printf("x is less");

所以这是优化的东西(糟糕的优化)。

顺便说一句 - 无论优化级别设置如何,VC 2008 都会在此处产生正确的输出。

例如 - VC 优化(在完全/最大优化级别)代码只留下:

printf("x is grater");

我每天都更喜欢我的编译器 ;-)

于 2013-11-12T07:30:54.067 回答
1

负零仍然为零,因此 +0 == -0 和 -0 < +0 为假。它们是相同值的两种表示。只有少数操作会有所不同:

  1. 1 / -0 = -无穷大,而 1 / +0 = +无穷大。
  2. sqrt(-0) = -0,而 sqrt(+0) = +0

可以通过几种不同的方式创建负零:

  1. 正数除以-infinity,或负数除以+infinity。
  2. 对负数产生下溢的操作。

这可能看起来相当晦涩难懂,但这是有充分理由的,主要是为了使涉及复数的数学表达式保持一致。例如,请注意,1/√(-z)==-1/√z除非您像我上面那样定义平方根,否则身份是不正确的。

如果您想了解更多详细信息,请尝试查找 William Kahan 的Branch Cuts for Complex Elementary Functions 或 Much Ado About Nothing's Sign Bit in The State of the Art in Numerical Analysis (1987)。

于 2013-11-12T06:42:07.403 回答