计算机存储小数偏差
❶ 为什么用%g存储的小数有变化
这涉及到两个方面的问题:
①电脑对浮点数(float)的表述。32位对浮点数的表达是:0~22位=尾数;23~30是指数,31位则是符合位。说白了就是十进制的小数部分是按照1/2+1/4+1/8+....这样的方式去逼近的,因此存在误差,也就是所谓的{存储精度}的问题。上面的121.6234其实电脑中的16进制数是:0x42f33f2e,再转换回10进制≈121.62339782714844,不同的编译器在不同的机器上,还有些许的误差。因此虽然文件中是121.6234,但读取到电脑内存中时按二进制或16进制存储,在printf时,按格式又转换,因此二者之间存在转换误差。
②%f和%g的区别。不带控制长度的%f,只表示6位精度(即小数点后面),因此%f≈121.623398,而%g则是{最多}6位(有效位含小数点前后),因此%g≈121.623。
而%.9g则表示最多有效位9位,这个处理是在0x42f33f2e(121.62339782714844)这个数基础上作的取舍,≈121.623398(...78四舍五入)。
也正是这个原因,高精度浮点运算有专门的库。
③ 可以用double替代float提高精度。因为在电脑中,double是64位,尾数部分有52位表示,11位指数位和1个符号位构成。121.6234 = 1.216233978271484375E2 = 0x405E67E5C91D14E4,因此更逼近121.6234. 演示代码如下:
#include<stdio.h>
intmain(intargc,charconst*argv[])
{
floata=121.6234;
doubled=121.6234;
printf("%.9g%f ",a,a);
printf("%.9g%f ",d,d);
return0;
}
运行:
121.623398121.623398
121.6234121.623400
❷ excel计算数据不一致怎么办
换一台电脑试试吧,应该是浮点小数产生的误差,可能换一台电脑就可以了。
以下是摘自excelhome论坛,来自灰袍法师的一篇详细介绍:
很多人在日常使用Excel,可能都没有注意到浮点小数带来的计算误差问题
因为日常使用的运算结果,肯定都是四舍五入之后的结果,可以排除浮点误差的影响
但是,浮点小数的误差,也会出现在运算的过程,有可能导致最终结果出错。
比方说 countif(A1:A10000,"=B1")这样的简单统计,也有可能出错。
附件生成5万个随机小数(四舍五入到2位小数位),加上然后马上减去同一个整数
对比计算前后的数值是否相等(数学上当然是绝对相等的,但是电脑的运算结果就不一定了。。。。。。)
附件会自动找出一批在你的电脑上会出现浮点小数误差导致错误的运算。
出现浮点小数运算误差的原因很简单,小数有无穷多个
甚至一个小数也有无穷多位,如十进制的1/3,或者二进制的0.1
所以计算机存储小数的时候,必定只能存储所有小数的一部分,而无穷小数则必须截断
因此,一个小数有时候就只能取一个接近值而不是精确值
而对应的浮点数运算,也只能得到接近值,而不是精确值
不同的CPU,比方说Intel的跟AMD的,或者奔腾跟赛扬,在硬件上对于截断的位置是不一样的
所以,同一个运算在不同的机器就可能有不同的结果
这也是为什么论坛经常有人说xx运算不正确,然后回帖的人说我的机器没事,其实就是CPU不同而已
另一方面,不同的软件,内部计算的时候,也许用了不同的CPU硬件实现的数据类型,或者精度设置也不一样,
所以,同一个运算在不同的软件也可能有不同的结果
编程,写公式要注意,假设 x,y 都是浮点数,er。。。。。。excel的每个小数单元格都是浮点数
那么永远不要写 if x=y 这样的句子,因为很可能数学上相等的x和y,在计算机内部是不等的
应该写成 if |x-y| / max(|x|,|y|) <= 0.0000000000001 之类
或者简单一点,用if round(x) = round(y) 来判断,这样最末一位的尾数浮点存储误差就不会影响整个数值了。
幸运的是,整数和定点小数不会受影响,编程时应该优先考虑使用整数和定点小数类型
另一方面,即使浮点小数可以完全表示我们要计算的数值,但是计算结果却也有可能产生误差
浮点,定点的意思是指小数点的位置
定点小数:小数点位置固定。
以十进制为例,假设一个数值类型可以有6个十进制位置,那么定点类型无须记录小数点位置,可以有以下类型:
整数类型,小数点位置就一定是个位后面,能够表达的最精确数字就是1,能够表达的范围是 000000 - 999999
两位小数类型,小数点位置就一定是百分位,能够表达的最精确数字就是0.01,,能够表达的范围是 0000.00 - 9999.99
。。。。。。等等
浮点小数:小数点位置可以变动,并且需要额外的记录去描述这个变动的小数点位置。
假设这里把其中一个位置用于记录小数点位置(可变范围 0-9),并且规定:
小数点位置取5,表示精度是1,小数点在个位后面,这个数值类型有0个小数位,可以表示 00000 到 99999 的数 (注意:这里只有5位有效数字)
小数点位置取6,表示精度是 0.1,小数点在十分位后面,这个数值类型有1个小数位,可以表示 0000.0 到 9999.9 的数
小数点位置取9,表示精度是 0.0001,小数点在万分位后面,这个数值类型有4个小数位,可以表示 0.0000 到 9.9999 的数
......
小数点位置取4,表示精度是 10,表示小数点在十位,这个数值类型可以表示 00000 x 10 到 999990 的数,精度是 10
......
小数点位置取0,表示精度是 100000,表示小数点在十万位,这个数值类型可以表示 00000 x 100000 到 9999900000 的数,精度是 100000
可见浮点小数通过可变的小数位置,使一个数值类型可以用一部分表示有效数字,另一部分表述每一单位有效数字的倍率
从而灵活地表示很大范围的数值,代价是:由于用了一部分记录内容去记录小数点位置,所以有效数字的长度比定点小数要低。
而且,一些定点数运算不会出现的问题,在浮点数运算会出现
如两个数相加
如果第一个浮点数是 100.01,第二个浮点数是 9999900000
按上述规则,这两个都是合法的浮点数,可是它们的和 99999000100.01 却无法用同一个浮点数类型表示出来。
一般计算机碰到这种情况,就会自动按比较大的数值来四舍五入,于是
100.01 + 9999900000 = 9999900000 (出现了100.01的误差)
这也是浮点数误差产生的一个原因:小的数值被大的数值“吸收”了。
要在Excel证明这一点就太简单了,因为excel的double类型浮点小数只有15个有效数字(即最多记录15个十进制数字)
所以Excel的单元格运算 12345012345678900000 + 12345.0123456789 = 12345012345678900000
更多的浮点小数知识,可以搜索论坛或者网络。
http://support.microsoft.com/kb/78113
❸ excel表 小数点只有两位的数据求和,出现误差怎么解决
原因:在Excel进行计算时在计算机中是转换成二进制进算然后保留数值的,所以会出现误差。
解决方法:
1、打开excel表格,在单元格A1中输入数字“2.88”,在单元格B1中输入数字“5.89”。
❹ 在excel里面运算,小数点后面的数字有时候有微小偏差,怎么回事
计算机运算用二进制,在和十进制转换的时候产生的浮点运算偏差,在外面套个round函数即可,假如你的运算精度是小数点后2位,那么在外面套个round(原来公式,3)即可
❺ C语言中实数计算和存储为什么有微小的误差
计算机中表示浮点数是采用近似值的~
这个问题可以说是计算机用有限的位来表示无限的数,因为位数有限计算机中储存的数自然不可能是连续的,应该是离散的值。当某个值它不能精确的表示时,它就要决定用它附近的值了。
假设有一台这样的机器,它能表示1.0 1.2 1.4 1.8(只能精确到小数后一位),如果我要用到1.25呢,它可能就会用1.2来代替了。当然位数越多,表示的值就越精确,所以double 会比float 精确。
❻ 计算机实数存储误差
这是因为计算机保存浮点数时,
是把数看作a*(2^b)这样的形式的,而不是我们直观上认为的以10为底数,
在计算机内部处理时是以2为底数的。
即将数转换成以2为底的“科学计数法”的形式,
再由这个形式反转换成10进制形式,
但是由于数据有位数的限制,
所以有些数转换成二进制计数形式后位数超出了限制的位数,那么超出的位就被截去了,
那么转换回来时得到的数就会与原数有偏差,不同的数这个偏差是不同的,
有可能在小数点后第7位,也有可能在第8位,也有可能在其他位数,
但是能保证第6位之前是正确的。