Python保留小数位末位为5时为什么会舍去

先看代码:

print("float,22.95保留1位小数" ,float('%.1f' % float(22.95)))
print("float,22.85保留1位小数" ,float('%.1f' % float(22.85)))
print("round保留一位小数:" ,round(22.95, 1))
# float,22.95保留1位小数 22.9
# float,22.85保留1位小数 22.9
# round保留一位小数: 22.9

惊奇的发现22.95四舍五入后结果为22.9;竟然和22.85四舍五入结果一样。

 

round( )函数简介

菜鸟教程中介绍到,round() 函数作用就是,返回浮点数x的四舍五入值。返回值为x的四舍五入值。n为保留的小数位数,不加n则只保留x四舍五入后的整数部分。

 

特殊的情况,不是四舍五入

显然结果不符合四舍五入的规则。为什么会这样呢?原因是:round()函数只有一个参数,不指定位数的时候,返回一个整数,而且是最靠近的整数,类似于四舍五入,当指定取舍的小数点位数的时候,一般情况也是使用四舍五入的规则,但是碰到.5的情况时,如果要取舍的位数前的小数是奇数,则直接舍弃,如果是偶数则向上取舍。

小数位的四舍五入在项目中经常用到,这就是上面提出22.95变成了22.9,那 如何才能变成23.0呢?

查找原因

通过Decimal函数查找下原因

print(Decimal(22.95))
print(Decimal(22.85))
# 22.949999999999999289457264239899814128875732421875
# 22.85000000000000142108547152020037174224853515625

根本原因:实际22.95用二进制转化的是有精度损失.部分小数无法完全用二进制表示。

这也就是为什么有的5可以进,有的就不行,如上代码22.85就可以正常进位。

round 本身没有问题,而是二进制保存的值有点误差导致的.

正确的解决方法

from decimal import Decimal, ROUND_HALF_UP
def numTrans(n, d=2):
    s = '0.' + '0' * d
    return Decimal(str(n)).quantize(Decimal(s), rounding=ROUND_HALF_UP)
print("numTrans22.95保留1位:",numTrans(22.95,1))
# numTrans22.95保留1位: 23.0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值