python比较靠谱的保留小数方法

最近遇到一个神奇的问题:

>>> round(0.215,2)
0.21
>>>

而我想要的结果是0.22,这个应该是二进制存储的原因。那么如何避免呢?

找了半天找到一个办法,贴在此处记录下:

import decimal

>>> aa = decimal.Decimal('0.215')
>>> aa.quantize(decimal.Decimal('1.00'))
Decimal('0.22')
>>>

貌似好点了,继续实验下:

>>> from decimal import Decimal
>>> Decimal('0.125').quantize(Decimal('1.00'))
Decimal('0.12')
>>> Decimal('0.375').quantize(Decimal('1.00'))
Decimal('0.38')

又有点儿意外了,原来quantize还有一个参数rounding,表示进位方式,默认值为ROUND_HALF_EVEN,此时精确小数点是如果遇到5,会是遵循前一位数字的奇进偶舍,

奇进偶舍简单解释:

例如对于一个小数a.bcd,需要精确到小数点后两位,那么就要看小数点后第三位:

  1. 如果d小于 5,直接舍去
  2. 如果d大于 5,直接进位
  3. 如果d等于 5:
    1. d后面没有数据,且 c 为偶数,那么不进位,保留 c
    2. d后面没有数据,且 c 为奇数,那么进位,c 变成(c + 1)
    3. 如果d后面还有非 0 数字,例如实际上小数为a.bcdef,此时一定要进位,c 变成(c + 1)

 

那么我们需要在quantize中指定进位方式为ROUND_HALF_UP

from decimal import *
>>> Decimal('0.125').quantize(Decimal('1.00'), rounding=ROUND_HALF_UP)
Decimal('0.13')
>>> Decimal('0.385').quantize(Decimal('1.00'), rounding=ROUND_HALF_UP)
Decimal('0.39')
>>>

 

参考:https://www.v2ex.com/t/550492

posted @ 2020-04-08 14:13  小哥豪  阅读(820)  评论(0编辑  收藏  举报