工作中遇到很大的浮点数,导致浮点数精度错误

问题描述
  • 遇到一个特别大的浮点数,其整数位超过了亿级单位,其小数位精度错误,导致计算错误

问题原因
  • 尝试直接以字符串的方式打印该数值,发现结果已经错误;确认问题原因是因为将浮点数转化为字符串时已经错误,导致后续的错误
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

上一篇:7.5 每日三题


下一篇:浮点运算-争议与思考_python_2021-07-05