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
,需要精确到小数点后两位,那么就要看小数点后第三位:
- 如果
d
小于 5,直接舍去- 如果
d
大于 5,直接进位- 如果
d
等于 5:
d
后面没有数据,且 c 为偶数
,那么不进位,保留 cd
后面没有数据,且 c 为奇数
,那么进位,c 变成(c + 1)- 如果
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