Python 的 Decimal的错误计算

摘要 阐述在使用 Python的 Decimal类时,可能产生的错误计算。

在 详述 BigDecimal 的错误计算 中,笔者较为详细地说明了 Java的 BigDecimal可能出错的原因。类似地,Python的 decimal模块中有个 Decimal类,也可用于高精度的十进制运算,并且能够避免由于浮点数表示不精确带来的精度问题。但是,相仿地,由于有一些参数要设置,所以亦会出现参数不同结果不一致现象。

例1. 不妨重新讨论 计算机的错误计算(一百七十七)中多项式(稍作修改:将小数部分去掉,变成整数)。

已知

计算

代码如下:

python 复制代码
from decimal import Decimal, getcontext
base = Decimal(234) # 定义基数
terms = [ # 计算每一项
    Decimal(134450) * base ** 12,
    Decimal(-31470000) * base ** 11,
    Decimal(2030000) * base ** 10,
    Decimal(1350000) * base ** 9,
    Decimal(1680000) * base ** 8,
    Decimal(1120000) * base ** 7,
    Decimal(748000) * base ** 6,
    Decimal(187000) * base ** 5,
    Decimal(46800) * base ** 4,
    Decimal(-140) * base ** 2,
    Decimal(7666044)]
print(sum(terms)) # 计算总和,输出结果

这时,输出为 1381004:

然而,准确值是 204 . 因此,代码输出的是错误结果。

例2. 用 Python的 Decimal编程计算

代码如下(来源于一大模型):

python 复制代码
from decimal import Decimal, getcontext

getcontext().prec = 50 # 设置精度,这里设置为50位小数

base = Decimal('23.67') # 定义数值
exponent = Decimal('65.5')

part1 = base ** exponent # 计算 23.67^65.5

part2 = (exponent * base.ln()).exp() # 计算 exp(65.5 * ln(23.67))

result = part1 - part2 # 计算差值

print(result)

运行后,输出为 -1E+41(显然是错误结果。正确值是0):

另外,getcontext().prec 不同,那么输出也不同。

点评:

(1)例1可以通过提高精度获得正确结果。

(2)例2不行。

(3)对于例1,虽然可以通过提高精度获得正确值,但是,用户不确定究竟 getcontext().prec 设为多少。只能是通过实验进行猜测。正像有学者评价数学软件一样:"The multiprecision ... in Mathematica and Maple is not very useful ..., because the working precision must be specified by the user and this naturally implies some guess work"1。

(4)getcontext().prec 的默认值是28 . 因此,例1中所有运算的结果应该是保留28位十进制有效数字。

参考文献

1 Cuyt A, Verdonk B, Becuwe S, et al. A remarkable example of catastrophic cancellation unraveled. Computing, 2001, 66: 309--320

相关推荐
XMXFS1 分钟前
小红书推荐算法底层逻辑解析:用数据思维做内容优化
python·算法·新媒体运营·推荐算法
hans7748829683 分钟前
仅根据BMI反推身高和体重?还真能做到!只需要简单的数论知识~
python·数学
追光者4944 分钟前
我把 55 篇自动化日志翻了一遍:最容易出事的是这 4 个地方
python·自动化运维
2601_962885721 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python
打工仔折腾 AI1 小时前
LangChain 工具调用实战:从 Tool 定义到 Agent 执行链路拆解
java·前端·人工智能·后端·python·langchain·ai agent 实战
hhb_6181 小时前
Flask+SQLite实现用户管理接口
python·sqlite·flask
全栈练习生1 小时前
RAG 准确率保障的体系化方案
python·ai
秋秋小事1 小时前
python 基础知识总结(一)
python
蜗牛互联网1 小时前
Python调用Gemini Structured Outputs实现工单路由门禁
java·开发语言·人工智能·python
TomEval2 小时前
【测AI】第12篇:NLP / CV / 语音 —— 三大 AI 方向速通
人工智能·python·自然语言处理·aigc·测试用例