双值为负零

时间:2013-11-12 06:27:37

标签: c

我有一个程序示例:

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

为什么控件进入第一个语句 - x更少。什么是-0.000000?

3 个答案:

答案 0 :(得分:9)

IEEE 754定义了一个非常常用的标准浮点数。您可以看到其结构here

  

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

  (−1)^s × c × bq
  

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

Double FP number

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

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

x = +0.0;
y = -0.0;

然后你应该看到:

(x -y) == 0

然而,对于x,OP的代码将使用“x更大”,而对于y,它将使用“x is less”。

修改: ArturanswerJeffrey Sax对此回答的评论澄清了x < 0的测试中的差异OP的问题实际上是编译器优化,实际上,x < 0的正面和负面0的测试应始终为false

答案 1 :(得分:2)

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

如果您能够看到装配输出的样子 - 我打赌您只会看到电话:

printf("x is less");

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

BTW - 无论优化级别如何设置,VC 2008都会在此生成正确的输出。

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

printf("x is grater");

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

答案 2 :(得分:1)

负零仍然为零,所以+0 == -0和-0&lt; +0是假的。它们是具有相同价值的两种表示。只有少数几个操作会产生影响:

  1. 1 / -0 = -infinity,而1 / +0 = +无穷大。
  2. sqrt(-0)= - 0,而sqrt(+0)= + 0
  3. 可以通过几种不同的方式创建负零:

    1. 将正数除以-infinity,或将负数除以+无穷大。
    2. 在负数上产生下溢的操作。
    3. 这可能看起来相当模糊,但有充分的理由,主要是使涉及复数的数学表达式保持一致。例如,请注意标识1/√(-z)==-1/√z不正确,除非您像我上面那样定义平方根。

      如果您想了解更多细节,请尝试在数值分析的最新进展中找到William Kahan的复杂基本功能的分支切割,或者多关于无标志位 < / em>(1987)。