关于C#:为什么相同的值float和double不同


Why same values differ with float and double

本问题已经有最佳答案,请猛点这里访问。

考虑这个计划

1
2
3
4
5
6
float a = 0.7f;

if (a < 0.7)
{
    Console.WriteLine("Less");
}

输出为Less。为什么??


因为0.7不具有与floatdouble完全相同的表示:它不是2的负幂的确切总和。

很巧,0.7作为a的最接近的表示是float近似于0.69999998807907104492,而最接近的double表示是0.69999999999999995559。如您所见,double稍大一点,这可以解释程序的行为。

下面是一个小的演示,您可以运行它来查看系统上的值:

1
2
printf("%20.20f %20.20f
"
, 0.7, (float)0.7);

(IDeone上的现场演示)。

这里的教训是,您不应该期望doublefloat表示的数学上相等的数字进行正确的比较以获得相等。在浮点系统中,只有一小部分分数可以表示为精确数字。

由于绝大多数分数都是近似的,所以最好将其与某种程度的公差进行比较。例如,不写if (a == 0.7),你应该写if (abs(a - 0.7) < 1E-8)


你在不知情的情况下在代码中比较苹果和土豆。

1
2
3
4
5
float a = 0.7f; //"0.7f" is a float
if(a< 0 .7)     //"0.7" is a double
{
    Console.WriteLine("Less"); //You'll see it because of different representations
}

如果您匹配数字类型,您的支票将按预期工作:

1
2
3
4
5
float a = 0.7f;
if(a < 0.7f)
{
    Console.WriteLine("Less"); // You won't see this
}

这就是为什么数字不应该硬编码的原因。修复代码的最佳方法:

1
2
3
4
5
6
float check = 0.7f;
float a = 0.7f;
if(a < check)
{
    Console.WriteLine("Less"); // You won't see this either
}