首页 > 解决方案 > 如何在python中存储具有后缀零的所需精度的十进制数?

问题描述

请注意 python 解释器中的以下结果。

>>> b=245.353
>>> print('%.50f'%b)
245.35300000000000864019966684281826019287109375000000

小数点后第 14 位之后,除零以外的数字开始出现,并一直保持到第 44 位。

Floating Point Arithmetic: Issues and Limitations中的Python 文档提到了这个限制,但文档中提到的解决方案在某些情况下不起作用,如下所述。

为了测试它如何影响算术运算的结果b,我尝试了一些乘法。

将 5.132435246464... 与 python 显示的 b 值相乘,最多保留 50 位小数。

>>> print('%.50f'%(5.132435246464363423432432432342432324342*245.35300000000000864019966684281826019287109375000000))
1259.25838502577107647084631025791168212890625000000000

将 5.132435246464... 与 b 相乘

>>> print('%.50f'%(5.132435246464363423432432432342432324342*b))
1259.25838502577107647084631025791168212890625000000000

将 5.132435246464... 与 245.353 相乘

>>> print('%.50f'%(5.132435246464363423432432432342432324342*245.353))
1259.25838502577107647084631025791168212890625000000000

所有 3 个结果完全相同。

为了检查真实的结果,我编写了一个程序,将 2 个数字逐位相乘,就像在笔和纸上所做的那样,以免失去准确性。它缓慢但准确。

现在用我的程序做同样的计算——

将 5.132435246464... 与 python 显示的 b 值相乘,小数点后 50 位

5.132435246464363423432432432342432324342 * 245.35300000000000864019966684281826019287109375000000 
= 1259.25838502577100337468290116624347509546633362424989047667622799053788185119628906250000000

将 5.132435246464... 与 245.353 相乘

5.132435246464363423432432432342432324342 * 245.35300000000000000000000000000000000000000000000000 
= 1259.25838502577095902941759457251279807428272600000000000000000000000000000000000000000000000

这两个结果彼此不同,也与前 3 次操作的结果不同。

结果从小数点后第 14 位开始有所不同。

文档建议使用 Decimal 和 Fraction 库。

分数库

>>> g = Fraction('245.353')
>>> g
Fraction(245353, 1000)
>>> print('%.50f'%g)
245.35300000000000864019966684281826019287109375000000

更明确并没有帮助。

>>> g = Fraction('245.35300000000000000000000000000000000000000000')
>>> g
Fraction(245353, 1000)
>>> print('%.50f'%g)
245.35300000000000864019966684281826019287109375000000

十进制库也会发生同样的事情

>>> d = Decimal('245.353')
>>> d
Decimal('245.353')
>>> print('%.50f'%d)
245.35300000000000864019966684281826019287109375000000

更明确

>>> d = Decimal('245.353000000000000000000000000000000000')
>>> d
Decimal('245.353000000000000000000000000000000000')
>>> print('%.50f'%d)
245.35300000000000864019966684281826019287109375000000

这严重影响了应用数值数学程序。

标签: python

解决方案


推荐阅读