不同符号表达式结果

2024-04-25 14:56:53 发布

您现在位置:Python中文网/ 问答频道 /正文

首先我想指出我是个彻头彻尾的笨蛋。你知道吗

我正试图用这个sympy表达式创建一个Custom Formula-based Measurement类:

from sympy import Symbol, S, floor, sympify, Float
SU = Symbol('millimeter')
exp = S(20.0) + floor((((SU-S(212.5)) / S(10.0))) / S(0.5)) * S(0.5)

我面临的问题是,对于相同的SU,我会根据表达式的求值方式得到不同的结果。我的意思是:

>>> exp.subs(SU, 215)
20.0000000000000
>>> exp.evalf(subs={SU: 215})
0.e+1 #This is actually 16.0 when: float(exp.evalf(subs={SU: 215}))

更有趣的是,只有当SU在[213:217]之间时(当我期望结果是20.0)这个问题才存在 其余的价值观都很好(AFAIK)

>>> exp.subs(SU, 212)
19.5000000000000
>>> exp.evalf(subs={SU: 212})
19.50
>>> exp.subs(SU, 218)
20.5000000000000
>>> exp.evalf(subs={SU: 218})
20.50

对这种奇怪的行为有什么看法吗?你知道吗


Tags: fromimport表达式customsymbolsubased笨蛋
1条回答
网友
1楼 · 发布于 2024-04-25 14:56:53

这是由于精度值不正确造成的。该错误是reported,并且已在GitHub上提供的当前版本的SymPy中更正;SymPy>;1.1.1的版本将不会有此错误。你知道吗


subs的输出使用srepr提供了一些解释:

x = Symbol('x')
srepr((floor(x)+20).evalf(subs={x:0.5}))

输出是Float('16.0', precision=1)。这是二进制精度。SymPy认为floor的输出恰好为零时,只有一位精度。因此它随后会相应地截断加上的+20,精确到2的幂。你知道吗

当然,这是一个错误。有几个与Float类和舍入相关的开放问题,例如this one;它们可能是相关的。你知道吗

解决方法是避免evalf(subs=dict)构造(是否有文档记录?)。按自然顺序使用方法:替换,然后评估,给出正确的结果:

srepr((floor(x)+20).subs({x:0.5}).evalf())
"Float('20.0', precision=53)"

相关问题 更多 >