我有一个程序示例:
int main()
{
double x;
x=-0.000000;
if(x<0)
{
printf("x is less");
}
else
{
printf("x is greater");
}
}
为什么控制在第一条语句中 - x is less 。什么是-0.000000?
我有一个程序示例:
int main()
{
double x;
x=-0.000000;
if(x<0)
{
printf("x is less");
}
else
{
printf("x is greater");
}
}
为什么控制在第一条语句中 - x is less 。什么是-0.000000?
IEEE 754 定义了一个非常常用的标准浮点数。你可以在这里看到它的结构:
有限数,可以是基数 2(二进制)或基数 10(十进制)。每个有限数由三个整数描述:s = 符号(零或一),c = 有效数(或“系数”),q = 指数。有限数的数值是
(−1)^s × c × bq
其中 b 是基数(2 或 10)。例如,如果符号为 1(表示负数),有效数字为 12345,指数为 -3,底数为 10,则数字的值为 -12.345。
因此,如果分数为 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
.
内森是对的,但有一个问题。通常大多数浮点/双精度操作由协处理器执行。然而,一些编译器试图变得聪明,而不是让协处理器进行比较(它将 -0.0 和 +0.0 视为 0.0)只是假设因为你的x变量有减号,这意味着它应该被视为负数并优化你的代码。
如果您能够看到汇编输出的样子 - 我敢打赌您只会看到调用:
printf("x is less");
所以这是优化的东西(糟糕的优化)。
顺便说一句 - 无论优化级别设置如何,VC 2008 都会在此处产生正确的输出。
例如 - VC 优化(在完全/最大优化级别)代码只留下:
printf("x is grater");
我每天都更喜欢我的编译器 ;-)
负零仍然为零,因此 +0 == -0 和 -0 < +0 为假。它们是相同值的两种表示。只有少数操作会有所不同:
可以通过几种不同的方式创建负零:
这可能看起来相当晦涩难懂,但这是有充分理由的,主要是为了使涉及复数的数学表达式保持一致。例如,请注意,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)。