浮动是不精确的

时间:2013-08-09 06:00:51

标签: c gcc clang c99

我很困惑。我没有解释为什么在使用double数据类型时此测试通过但在使用float数据类型时失败。请考虑以下代码片段。

float total = 0.00;

for ( int i = 0; i < 100; i++ ) total += 0.01;

人们会预期total为1.00,但它等于0.99。为什么会这样?我用GCC和clang编译,两个编译器都有相同的结果。

2 个答案:

答案 0 :(得分:4)

试试这个:

#include <stdio.h>

int main(){
    float total = 0.00;
    int i;
    for (i = 0; i < 100; i++)
        total += 0.01;

    printf("%f\n", total);

    if (total == 1.0)
        puts("Precise");
    else
        puts("Rounded");
}

至少在大多数机器上,你会获得“Rounded”的输出。换句话说,结果恰好足够接近,当它打印出来时,它是圆形的,所以看起来恰好是1.00,但事实并非如此。将total更改为double,您仍然可以获得相同的结果。

答案 1 :(得分:3)

十进制0.01的值表示为系列:a1 *(1/2)+ a2 *(1/2)^ 2 + a3 *(1/2)^ 4 +等其中{{1}是零或一。

我留给你来弄清楚a1,a2的具体值以及需要多少小数位(aN)。在某些情况下,小数部分不能用有限的(1/2)^ n值表示。

对于此系列总和为0.01的十进制要求aN超出存储在浮点数中的位数(位的全字减去符号和指数的位数)。但由于double有更多的位,所以精确定义了0.01十进制可能/可能/可能(你做计算)。