问题描述
- 遇到一个特别大的浮点数,其整数位超过了亿级单位,其小数位精度错误,导致计算错误
问题原因
- 尝试直接以字符串的方式打印该数值,发现结果已经错误;确认问题原因是因为将浮点数转化为字符串时已经错误,导致后续的错误
b = 1100157865106.26789
print str(b)
--- 输出结果 ---
1.10015786511e+12
解决
- 使用 decimal 模块进行精度的四舍五入,但是 decimal 模块需要使用字符串四舍五入才会精确
#!/usr/bin/python
# -*- encoding: utf-8 -*-
from decimal import Decimal, ROUND_HALF_UP
def setDecimal(data, dec_place='0.00'):
print '--->直接将data转化为字符串, 精度会出现丢失: {}'.format(str(data))
n1 = str(Decimal(data))
print '--->将data转化为decimal,再转化为字符串: {}'.format(n1)
n2 = Decimal(n1).quantize(Decimal(dec_place), rounding=ROUND_HALF_UP)
print '--->再将n1进行四舍五入,精度依然会有错误: {}'.format(n2)
# 将浮点数转化为decimal,保留比期望更高的精度,再转化为字符串
data = Decimal(str(Decimal(data))).quantize(Decimal(dec_place + '0000'), rounding=ROUND_HALF_UP)
print '--->将data转化为decimal,保留比期望更高的精度,再转化为字符串,再转化为字符串: {}'.format(data)
# 再通过decimal模块进行四舍五入
return Decimal(str(data)).quantize(Decimal(dec_place), rounding=ROUND_HALF_UP)
a = 0.215
b = 1100157865106.26789
print '--->{1}四舍五入结果正常: {1}'.format(a, setDecimal(a))
print '--' * 10
print '--->{1}四舍五入结果正常: {1}'.format(b, setDecimal(b))
---> 输出结果 <---
--->直接将data转化为字符串, 精度会出现丢失: 0.215
--->将data转化为decimal,再转化为字符串: 0.2149999999999999966693309261245303787291049957275390625
--->再将n1进行四舍五入,精度依然会有错误: 0.21
--->将data转化为decimal,保留比期望更高的精度,再转化为字符串,再转化为字符串: 0.215000
--->0.22四舍五入结果正常: 0.22
--------------------
--->直接将data转化为字符串, 精度会出现丢失: 1.10015786511e+12
--->将data转化为decimal,再转化为字符串: 1100157865106.267822265625
--->再将n1进行四舍五入,精度依然会有错误: 1100157865106.27
--->将data转化为decimal,保留比期望更高的精度,再转化为字符串,再转化为字符串: 1100157865106.267822
--->1100157865106.27四舍五入结果正常: 1100157865106.27
Process finished with exit code 0