不同的症状表达结果

时间:2017-09-27 15:25:27

标签: python sympy

首先,我想指出我总共sympy个菜鸟。

我尝试使用此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

对这种奇怪行为的任何想法?

1 个答案:

答案 0 :(得分:3)

这是由于精度值不正确造成的。该错误是reported,已在GitHub上可用的当前版本的SymPy中得到纠正; SymPy的版本> 1.1.1不会有这个错误。

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

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)"