对于标题疑问,2.25-2.2!=0.05,那正确答案是什么呢?
print(2.25-2.2) #0.04999999999999982
事实证明,的确不等于0.05.那0.04999999999999982是怎么得来的呢?
Google:因为误差
误差是怎么产生的,为什么整数就能精确表示,而浮点数不能精确表示?
Google:因为整数和浮点数在计算机的存储方式不同
那浮点数跟整数相比,浮点数在计算机如何存储的呢?
Google:说来话长......
1.计算机的本质
追根究底,计算机工作的实质便是电压的高低切换,像电灯,高电位,电灯亮,低电位,电灯灭。为了表示这两种状态,便引入0和1。为了表示更多状态,便增加0和1的对数。32bit和64bit的计算机就是这样来的,代表了计算机内存存放待处理数据的大小。32bit的计算机内存大概在4G左右,64bit更多。
#32bit能表示的数值范围如下
00000000000000000000000000000000~11111111111111111111111111111111
2.浮点数存储方式
由于计算机不识别十进制,所以十进制数据都要转换为二进制保存。并且是以二进制的科学记数法进行保存
2.25 == 10.01 #(二进制)
== 1.001*2^1 #(二进制科学计数法)
# 2.25整数部分转换:2=10(除2取余法)
# 小数部分转换过程:0.25*2 = 0.5 取整数部分0 (乘2取整法)
# 0.5*2 = 1 取整数部分1
# 故小数部分0.25 = .01
浮点数转换为二进制科学计数法,由三部分组成符号位,指数位,尾数部分
这三部分在计算机中是怎么存储的呢?
以单精度float为例,float根据IEEE R32.24标准数据占32位,每部分存放规则如下:
说明:1.对于符号位,若值为正,则为0,若值为负,则为1
2.对于指数位,由于指数存在正指数和负指数,占一位,其余7位表示值的大小,故范围为-127~128.指数位采用移位存储方式,即元指数+127(00000000=>-127)~(11111111=>128)
3.对于尾数部分,由于第一位恒为1,所以实际表示并未考虑第一位,所以有效位为24位
那么2.25(即1.001*2^1)在计算机中存储方式为:
0(正) 10000000(1+127) 00100000000000000000000(.001)
2.2呢?
#利用十进制转二进制得2.2小数本分0.2采用乘2取整法过程:
0.2*2=0.4 0
0.4*2=0.8 0
0.8*2=1.6 1
0.6*2=1.2 1
0.2*2=0.4 0
......
# 不可能乘2恰好得到1.0
2.2=10.00110011001100110011001100110011001100110011001101...#(无限不循环)
=1.00011001100110011001100*2^1(尾数部分超过23位都被截去了)
!=2.2
那么2.25(即1.001*2^1)在计算机中存储方式为:
0(正) 10000000(1+127) 00011001100110011001100
可见,2.2的小数部分通过乘二取整法,永远无法恰好达到1,所以二进制尾数部分成无限不循环,超过23位的数据会直接被丢弃,导致与原十进制数据不相等。这也就是误差产生的根源。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。