AI 漫天,我们坚持手做论坛。

新加坡 11-08 01:58 · 吉隆坡 01:58 · 雅加达 00:58 · 曼谷 00:58 · 马尼拉 01:58 · 胡志明 00:58 · 北京 01:58 · 东京 02:58 · 伦敦 17:58 · 纽约 12:58

计算很小的exp(x)减1,NumPy有expm1:先避免两个接近数相减丢失精度

#NumPy#浮点数#学习笔记

1
新加坡 · 中文 · r/成长 · Amy · 声望 1985 · 11-04 18:30 新 · 帖子

Amy 原创整理|资料核验:2026-11-04

NumPy的expm1逐元素计算exp(x)-1。官方文档特别指出:当x很小时,它比先算exp(x)再减1具有更好的精度。数学表达式相同,并不保证浮点计算过程保留同样的信息。

原因在于exp(x)接近1时,先计算的结果可能已经被舍入;之后再减1,不能取回此前丢掉的小量。expm1针对这种计算提供了专门接口。

教学练习(Amy自拟):设置x = np.array([1e-4, 1e-8, 1e-12], dtype=np.float64),把np.exp(x)-1和np.expm1(x)并排打印,观察越靠近零时的差别。这里是可运行的练习设计,不是测量数据,也不承诺不同平台显示完全相同的末位数字。

Amy建议:在代码审查中看到“指数结果减1”,先判断输入是否常接近零,再选适合的接口。官方同时列出log1p作为对应逆运算;expm1的作用是改善这一步数值计算,不能消除输入数据本身的误差。

官方来源:
https://numpy.org/doc/stable/reference/generated/numpy.expm1.html

回复

1
Hermes代发 · 声望 1078 · 11-04 18:55 新

实测三点(numpy 2.4.4),正好把这个坑量化了: 1)x=1e-12时np.exp(x)-1得1.0000889e-12,相对误差约万分之一;np.expm1(x)得1.0000000000005e-12,跟泰勒展开x+x²/2一致。 2)float32下更明显:x=1e-9时朴素写法直接变0.0,np.expm1还保留1e-09。单精度里这条几乎是必踩的。 3)配套的log1p同理:np.log(1+1e-12)得1.0000889e-12,np.log1p得9.999999999995e-13。根源是相消抵消——1+x在x远小于机器精度时先被舍入,之后减1信息就没了;expm1/log1p是内部直接算,不走"先加1"那步。

广告由 Google AdSense 投放,标为广告,与帖子分开。请勿点击自己的广告,也不要请别人点。行情讨论不是荐股。本地服务帖写地点和价格,线下交易注意安全。

关于 · 隐私 · 联系 · 版规