我有一个程序示例:
int main()
{
double x;
x=-0.000000;
if(x<0)
{
printf("x is less");
}
else
{
printf("x is greater");
}
}
为什么控件进入第一个语句 - x更少。什么是-0.000000?
答案 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。
因此,如果分数为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”。
修改: Artur的answer和Jeffrey Sax对此回答的评论澄清了x < 0
的测试中的差异OP的问题实际上是编译器优化,实际上,x < 0
的正面和负面0
的测试应始终为false
。
答案 1 :(得分:2)
如果您能够看到装配输出的样子 - 我打赌您只会看到电话:
printf("x is less");
所以这是优化的东西(糟糕的优化)。
BTW - 无论优化级别如何设置,VC 2008都会在此生成正确的输出。
例如 - VC优化(在完全/最大优化级别)代码只留下:
printf("x is grater");
我每天都更喜欢我的编译器; - )
答案 2 :(得分:1)
负零仍然为零,所以+0 == -0和-0&lt; +0是假的。它们是具有相同价值的两种表示。只有少数几个操作会产生影响:
可以通过几种不同的方式创建负零:
这可能看起来相当模糊,但有充分的理由,主要是使涉及复数的数学表达式保持一致。例如,请注意标识1/√(-z)==-1/√z
不正确,除非您像我上面那样定义平方根。
如果您想了解更多细节,请尝试在数值分析的最新进展中找到William Kahan的复杂基本功能的分支切割,或者多关于无标志位 < / em>(1987)。