当我使用float而不是double时输出奇怪

#include <stdio.h>
void main()
{
    double p,p1,cost,cost1=30;
    for (p = 0.1; p < 10;p=p+0.1)
    {
        cost = 30-6*p+p*p;
        if (cost<cost1)
        {
            cost1=cost;
            p1=p;
        }
        else
        {
            break;
        }
        printf("%lf\t%lf\n",p,cost);
    }
    printf("%lf\t%lf\n",p1,cost1);
}

给出预期的输出,p = 3;

但是当我使用float时,输出有点奇怪。
#include <stdio.h>
void main()
{
    float p,p1,cost,cost1=40;
    for (p = 0.1; p < 10;p=p+0.1)
    {
        cost = 30-6*p+p*p;
        if (cost<cost1)
        {
            cost1=cost;
            p1=p;
        }
        else
        {
            break;
        }
        printf("%f\t%f\n",p,cost);
    }
    printf("%f\t%f\n",p1,cost1);
}

为什么第二种情况下p的增量在2.7之后变得很奇怪?

最佳答案

之所以会这样,是因为floatdouble数据类型将数字存储在以2为底的数字中。大多数以10为底的数字无法完全存储。使用float时,舍入错误的累加速度更快。因此,在内存有限的嵌入式应用程序之外,使用double通常更好或更容易。

要查看double类型的情况,请考虑以下代码的输出:

#include <stdio.h>
int main(void)
{
    double d = 0.0;
    for (int i = 0; i < 100000000; i++)
        d += 0.1;
    printf("%f\n", d);
    return 0;
}

在我的计算机上,它输出9999999.981129。因此,经过1亿次迭代,舍入误差使结果相差0.018871。

有关浮点数据类型如何工作的更多信息,请阅读What Every Computer Scientist Should Know About Floating-Point Arithmetic。或者,如akira在评论中所述,请参阅Floating-Point Guide

10-06 15:07
查看更多