Tru*_* Ha 19 floating-point ieee-754
可能重复:
比较C#中的double值时出现问题
我在其他地方读过它,但是真的忘记了答案,所以我再次问这里.无论你用任何语言编写它,我都不会结束这个循环(我用C#,C++,Java测试它):
double d = 2.0;
while(d != 0.0){
d = d - 0.2;
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*ers 32
浮点计算不是很精确.您将得到一个表示错误,因为0.2没有精确表示为二进制浮点数,因此该值不会完全等于零.尝试添加调试语句以查看问题:
double d = 2.0;
while (d != 0.0)
{
Console.WriteLine(d);
d = d - 0.2;
}
Run Code Online (Sandbox Code Playgroud)
2 1,8 1,6 1,4 1,2 1 0,8 0,6 0,4 0,2 2,77555756156289E-16 // Not exactly zero!! -0,2 -0,4
解决它的一种方法是使用类型decimal.
Jon*_*eet 27
(有一件事你并没有使用相同的变量,但我会认为这是一个错字:)
0.2不是0.2.它是最接近double0.2的值.当你减去的10倍,从2.0,你就不会结了正好 0.0.
在C#中,您可以更改为使用decimal类型,这将起作用:
// Works
decimal d = 2.0m;
while (d != 0.0m) {
d = d - 0.2m;
}
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为十进制类型确实表示精确到0.2的十进制值(在限制范围内;它是128位类型).所涉及的每一个价值都是精确可表现的,因此它起作用 什么是行不通的将是这样的:
decimal d = 2.0m;
while (d != 0.0m) {
d = d - 1m/3m;
}
Run Code Online (Sandbox Code Playgroud)
在这里,"第三个"并不完全可以表示,所以我们最终遇到了和以前一样的问题.
但总的来说,在浮点数之间进行精确的相等比较是个坏主意 - 通常你会在一定的容差范围内对它们进行比较.
我有关于从C#/ .NET上下文浮动二进制点和浮点小数点的文章,它们更详细地解释了一些事情.
小智 11
我记得买了一个Sinclair ZX-81,通过优秀的Basic编程手册,当我遇到第一个浮点舍入错误时,几乎回到了商店.
我永远不会想到人们在27.99998年之后仍然会遇到这些问题.