python疑问2:2.25-2.2!=0.05?

本文深入探讨了2.25-2.2不等于0.05的原因,详细解释了浮点数在计算机中的存储原理,并揭示了浮点运算误差产生的根本原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于标题疑问,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

0(正) 10000000(1+127) 00011001100110011001100

可见,2.2的小数部分通过乘二取整法,永远无法恰好达到1,所以二进制尾数部分成无限不循环,超过23位的数据会直接被丢弃,导致与原十进制数据不相等。这也就是误差产生的根源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值