危险的浮点数float

今天写程序又以为我见鬼了!最后查出来发现原来又是浮点数搞的鬼!

情况大致是这样的,我想要测试向量运算的速度,所以要对一个浮点数向量进行求和运算,代码如下:

int vect_size=100000000;
vector<float> vect1(vect_size,0.1);
float sum=0;
for(int i=0;i<vect1.size();++i){
	sum+=vect1[i];
}
printf("%f\n",sum);

10^8个0.1求和,地球人都知道结果应该是10^7,运行结果竟然是……2.097152*10^7

我了个擦!我读书少你也不能这么骗我啊!

当vect_size为10000时,运行结果为999.902893,说明错误是累加形成的,并非溢出之类的造成的。

注意我保留了小数点后这么多位,原因是在不同的电脑上运行,结果是相同的,即都会产生这么大的偏差。

如果我把float换成double,那么结果是没有问题的。

 

我猜想了一下原因:

float的精度有一定的上限,对于任何小数,float都只能是用一个最接近的数来表示,并不是完全一样的数,即float是不连续的。所以0.1在float中是不存在的,只存在0.100000001(举个例子~),而这个规则是float的定义造成的,并非编译器或运行环境决定的,所以在不同的电脑上运行结果相同。此外,double的精度更高,所以在1亿这个量级上还看不出误差。

是否真是这样,等有时间研究下float再说。

 

不过这么看,float真是蛮危险的,因为其反直觉,所以很有可能给程序造成一些意料之外的结果(就是我说的见鬼了)。

我上一次见鬼也是跟float有关,大致代码如下:

 

float f=0.1;
if(f==0.1){
   printf("equal!");   
}

当时还是用python写的,死活不通过……其实原因上面已经提到了。

float当真反直觉!代码中的不确定因素!

 

posted @ 2014-12-05 16:23  MindProbe  阅读(1687)  评论(0编辑  收藏  举报