python 四舍五入问题如何解决

python 四舍五入问题如何解决

实际业务场景中,我们需要对数据求和。但是发现两位小数的数据相加会得到十几位小数,对于这种情况我们需要对数据进行四舍五入,可是发现四舍五入过程有很对问题,对‘11.245’,‘11.255’,‘0.235’保留两位小数,预期结果分别为‘11.25’, ‘11.26’,‘0.24’如下:

1. 使用round()操作:

>>> round(11.245, 2)
11.24
>>> round(11.255,2)
11.26
>>> round(0.235, 2)
0.23

2. 使用“%.2f”

>>> ("%.2f")%(11.245)
'11.24'
>>> ("%.2f")%(11.255)
'11.26'
>>> ("%.2f")%(0.235)
'0.23'

3. 使用Decimal

>>> Decimal(11.245).quantize(Decimal('0.00'))
Decimal('11.24')
>>> Decimal(11.255).quantize(Decimal('0.00'))
Decimal('11.26')
>>> Decimal(0.235).quantize(Decimal('0.00'))
Decimal('0.23')

4. 分析原因

通过上面的结果可以发现,三种方法得到的结果一样,但是有些与预期的结果不符。为什么会出现这种情况,这主要原因是python中我们看到的数据实际上可能并不是真正的样子,对于刚才的三个数据在python我们看看实际上数值:

>>> Decimal(11.245)
Decimal('11.2449999999999992184029906638897955417633056640625')
>>> Decimal(11.255)
Decimal('11.2550000000000007815970093361102044582366943359375')
>>> Decimal(0.235)
Decimal('0.23499999999999998667732370449812151491641998291015625')

看到这里,貌似恍然大悟了,原来这些数据在python当中实际是这样的,怪不得会得到不一样的结果。
但是我们在看看下面的数据,你可能又蒙了:

>>> Decimal(0.125)
Decimal('0.125')
>>> round(0.125, 2)
0.12

0.125 在python中实际上就是0.125,但是这里为什么得到的结果不是 0.13呢。

原因

在python中保留小数要遵循奇进偶舍,下面来说说什么叫做奇进偶舍。
对于一个类似 a.bcde这样的小数,保留两位小数:

  1. 如果 d 小于 5, 直接舍去
  2. 如果 d 大于 5,直接进位
  3. 如果 d 等于 5:
    (1)d 后面没有数据并且 c 为偶数,那么不进位,保留c
    (2)d 后面没有数据并且 c 为奇数,那么进位,c为(c+1)
    (3)如果e为非0数字,那么进位,c为(c+1)

所以,进行四舍五入操作的时候,首先看实际的值是否与当前的值是否一样,如果不一样与,则根据实际的值进行四舍五入操作;如果一样,则采用的是奇进偶舍的方式进行操作。

这个时候就能理解为什么 0.125 保留两位小数后 得到的结果是 0.12,因为实际值就是0.125,所以使用奇进偶舍方法后得到的结果是 0.12。

5. 得到正确结果方法:

  1. 使用round()方法,保留两位小数可通过给原数加 0.001后再进行四舍五入:
>>> round(11.245 + 0.001, 2)
11.25
>>> round(11.255 + 0.001, 2)
11.26
>>> round(0.235 + 0.001, 2)
0.24

这里加了 0.001 的操作就是为了应对奇进偶舍的方法。

  1. 使用Decimal操作:
>>> from decimal import Decimal, ROUND_HALF_UP
>>> Decimal('11.245').quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
Decimal('11.25')
>>> Decimal('11.255').quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
Decimal('11.26')
>>> Decimal('0.235').quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
Decimal('0.24')

对于后面的数字为5的,通过向上取整的操作去进行操作。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值