关于python四舍五入产生的精度问题

情景介绍:

公司产品准备做推广。推出了满减优惠卷功能,这里的优惠卷金额分为固定金额优惠和折扣优惠。现在着重说一下的,就是折扣优惠计算的时候出现了浮点数精度问题,导致四舍五入出现差异。


数据库中的金额字段一般是选择整数类型,然后以分为单位,如果是固定折扣的加减是不会涉及到浮点数的,而当碰到折扣时候,就会出现浮点数精度的问题,

举一个简单的例子,假如商品价格是9分钱,使用了5折劵,那么支付金额就是4.5分钱,但是支付中一般只精确到分(一来容易计算,二来很多第三方支付平台类似微信目前都只支持精确到分)这里我们就需要对4.5分钱做一个取整处理,具体取整看产品逻辑,至于向上/下取整都比较容易,我们来讨论一下四舍五入的问题。

首先第一个方法是int函数,这是python的内置函数,但是这个取整就显得不太合理,因为int并不是四舍五入,而是类似向下取整,只获取小数点前面的数据。

利用int特性给参数加0.5可以强行达成四舍五入效果

这方法很取巧,虽然能解决问题,然后让我们继续看看有没有可用的函数解决了这个问题,不需要手动补0.5。

四舍五入,稍微搜一下就可以找到round函数,让我们试一下。


好玩的来了,在参数是4.4/4.6的时候,成功的四舍六入,但是当参数为4.5时,我们发现被0.5被舍弃了,参数为5.5时入1结果是6。实际是round这个函数的口诀是四舍六入五成双(成双指的保持小数点前一位是偶数),具体的关于这个可以看一下round四舍五入精度介绍这篇文档,关于浮点数为何会有精度问题建议看一下浮点数精度解析这篇文档。

那么round这个模块看来无法解决四舍五入的问题,这里找到一个decimal模块,阅读官方文档可以看到,这个模块有针对浮点数取整做处理。


其中quantize函数的第二个参数舍去规则可以参考这里。

额外提一句decimal模块返回的参数类型看上去是数字,可以进行加减乘除,但是无法被json序列化,如果需要,在外面穿一层int()的外衣。

以上

你可能感兴趣的:(关于python四舍五入产生的精度问题)