为什么我使用gcc编译出来这样的结果

#include
int main()
{
float a,b;
a=333333333333.0;
b=333333333333.333
printf("%f\n%f\n",a,b);
return 0;
}
/*最后结果为333333331986.000000;
333333331986.000000;*/

浮点数本来就有精度限制。

浮点数计算有误差。
将10进制数转换为二进制数,以及计算结果的二进制数再转回十进制数,这个也有误差。

你有那种市场上卖东西的人用的计算器么?
你可以做一个实验,你输入3.14159265359
然后输入除以10000000,再输入-1.1111111,再输入+1.1111111,再输入乘以10000000
按理说还是之前的值,但是结果不是,能是3.1415就不错了。

在我这边的结果是
333333331968.000000
不知道是不是楼主笔误,如果是的话,原因如下

float在gcc中的表示占用32bit,其中从高位到低位依次为:

1bit符号 7bit阶码 23bit尾数
详细可参考http://www.cnblogs.com/algorhythm/archive/2012/10/12/2721141.html

333333333333.0的二进制表示为

100 1101 1001 1100 0011 0111 0000 0101 0101 0101

表示成2进制的科学计数法,就是

1.00 1101 1001 1100 0011 0111 0000 0101 0101 0101 * 2^38

其中1.00 1101 1001 1100 0011 0111 0000 0101 0101 0101就是尾数, 38就是阶数
因为所有尾数的第1位都是1,所以float的尾数中是不包含第一位1的,也就是说,如果空间足够,float的尾数就是

00 1101 1001 1100 0011 0111 0000 0101 0101 0101

一共38位

但是前面说过float的尾数只有23bit,所以存储的时候就把后面多余的位数去掉,变成
00 1101 1001 1100 0011 0111 0

在转换成10进制打印的时候,实际计算的是

1.00 1101 1001 1100 0011 0111 0 * 2^38
也就是

100 1101 1001 1100 0011 0111 0 * 2^(38-23)


10172526 * 2^15 = 333333331968.000000

that's all. thx.