我很困惑。我没有解释为什么在使用double
数据类型时此测试通过但在使用float
数据类型时失败。请考虑以下代码片段。
float total = 0.00;
for ( int i = 0; i < 100; i++ ) total += 0.01;
人们会预期total
为1.00,但它等于0.99。为什么会这样?我用GCC和clang编译,两个编译器都有相同的结果。
答案 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十进制可能/可能/可能(你做计算)。