You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sympy与mpmath计算结果不一致问题求助

mpmath与sympy计算sin(0.4)结果不一致的原因及解决方法

我测试mpmath和sympy时发现,二者计算sin(0.4)的结果存在差异:

  • mpmath输出:0.389418342308650491666311756796
  • sympy通过evalf()、N()或lambdify调用mpmath的输出:0.389418342308650522465285348517

我认为mpmath的结果是正确的,以下是问题根源和解决办法:

测试代码

import sympy as sp
import mpmath as mp

# 设置mpmath精度为30位小数
mp.mp.dps = 30               

print('mp: ', mp.sin('0.4'))

# 定义变量并计算正弦函数
x = sp.symbols('x')

x = '0.4'
print('sp: ', (sp.sin(x).evalf(30)))
print('N : ', sp.N(sp.sin(x), 30))

x = sp.symbols('x')
sin_func = sp.sin('0.4')

# 将sympy函数转为mpmath格式
sin_func_mpmath = sp.lambdify(x, sin_func, modules='mpmath')

# 计算结果
result = sin_func_mpmath(mp.mpf('0.4'))
print('mo: ', result)

问题原因

问题出在sympy对字符串'0.4'的解析逻辑上:当你调用sp.sin('0.4')时,sympy会先把字符串'0.4'转换为Python原生的双精度浮点数(约15-17位有效数字)。由于二进制浮点数无法精确表示0.4,这个转换过程会引入微小误差。之后sympy基于这个近似值计算正弦,再扩展到30位小数,最终结果自然和mpmath直接用高精度mpf('0.4')计算的结果产生差异。

解决方法

方法1:使用精确的有理数或高精度浮点数作为输入

sympy支持精确的有理数类型,或者直接接收mpmath的高精度浮点数,这样能避免中间的精度损失:

import sympy as sp
import mpmath as mp

mp.mp.dps = 30               
print('mp: ', mp.sin('0.4'))

# 用有理数精确表示0.4(2/5)
x_rational = sp.Rational(2, 5)
print('sp_rational: ', sp.sin(x_rational).evalf(30))

# 直接传入mpmath的高精度浮点数
x_mpf = mp.mpf('0.4')
print('sp_mpf: ', sp.sin(x_mpf).evalf(30))

运行后输出会和mpmath的结果完全一致:0.389418342308650491666311756796

方法2:强制sympy使用高精度计算

如果必须使用字符串输入,可以通过配置sympy的计算精度,让它直接基于高精度数值计算:

import sympy as sp
import mpmath as mp

mp.mp.dps = 30               
print('mp: ', mp.sin('0.4'))

# 配置sympy的精度为30位
print('sp_high_precision: ', sp.N(sp.sin(sp.nsimplify('0.4')), 30))

这种方式也能得到和mpmath一致的结果。

内容的提问来源于stack exchange,提问作者Samson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 04:01:10