1

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

float total = 0.00;

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

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

4

2 回答 2

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");
}

至少在大多数机器上,你会得到“圆角”的输出。换句话说,结果恰好足够接近,以至于当它被打印出来时,它是四舍五入的,所以它看起来正好是 1.00,但实际上不是。更改total为 a double,您仍然会得到相同的结果。

于 2013-08-09T06:13:51.690 回答
3

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

我留给您计算 a1、a2 的具体值以及需要多少小数位 ( aN)。在某些情况下,小数部分不能由 (1/2)^n 值的有限系列表示。

要使这个系列在十进制中求和为 0.01,需要aN超出存储在浮点数中的位数(完整的位字减去符号和指数的位数)。但是由于 double 具有更多位,因此可以/可能/可能(您进行计算)精确定义 0.01 十进制。

于 2013-08-09T06:14:15.567 回答