Python四舍五入的误差与正确打开方式

引入

在Python中,负责四舍五入的函数是round(),很多人都会,它的用法如下: 

round(number, ndigits)

其中,number是要四舍五入的数字,ndgigits是要四舍五入的位数(小数点后计算),不填默认为四舍五入到个位,例如: 

或者:

 

print('%.你四舍五入的位数f' % 你要四舍五入的数)
print('{:.你要四舍五入的位数f}'.format(你要四舍五入的数))
print(f'{你要四舍五入的数:.2f}')

但是,显然没有这么简单,在有些数中,可能会: 

其他方法也是如此,下面就是我们的解决方案

解决方案

分析原因

其实原因很简单,在Python中,采用的是二进制运算,如果把1.035转为四舍五入20位(此处不能用round函数),执行:

print(f'{1.035:.20f}')

你应该会看到:1.03499999999999992006,这其实是Python进制转换的误差,如果四舍五入到第二位,第三位是4,小于5,会舍去,所以就会产生误差

处理方法

我们只需要使用Python内置的十进制运算(decimal)模块就可以了

import decimal # 导入decimal模块

n = decimal.Decimal('1.035') # 定义一个decimal.Decimal类型的变量n,值为1.035,必须是字符串

第三行的值必须要是字符串,不然还会有错,接下来,直接round就行

print(round(n, 2))

但是如果你的值是1.025,结果依旧为1.02,其实原因很简单,decimal模块默认四舍五入机制为:

如果5前一位是奇数,则进位,否则,舍去,解决方法也很简单,在import decimal下面,加一行代码:

decimal.getcontext().rounding = decimal.ROUND_HALF_UP

然后,结果就正确了。

我还写了一段代码,生成一个csv文件,可以看到各种算法的结果:

import decimal

decimal.getcontext().rounding = decimal.ROUND_HALF_UP
dn = decimal.Decimal('1.005')
n = 1.005
with open("四舍五入.csv", "w", encoding='utf-8') as f:
    f.write("base,round,f-string,decimal\n")
for i in range(10):
    with open("四舍五入.csv", "a", encoding='utf-8') as f:
        f.write(f"{n+(i/100)},{round(n+(i/100), 2)},{n+(i/100):.2f},{round(dn+decimal.Decimal(i/100), 2)}\n")
print("已将结果保存到四舍五入.csv")

用Excel或WPS打开生成的文件,你可以看到:

 base是原数,可以看到,只有decimal的结果是准确的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值