首先我想指出我是个彻头彻尾的笨蛋。你知道吗
我正试图用这个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
对这种奇怪的行为有什么看法吗?你知道吗
这是由于精度值不正确造成的。该错误是reported,并且已在GitHub上提供的当前版本的SymPy中更正;SymPy>;1.1.1的版本将不会有此错误。你知道吗
对
subs
的输出使用srepr
提供了一些解释:输出是
Float('16.0', precision=1)
。这是二进制精度。SymPy认为floor
的输出恰好为零时,只有一位精度。因此它随后会相应地截断加上的+20,精确到2的幂。你知道吗当然,这是一个错误。有几个与Float类和舍入相关的开放问题,例如this one;它们可能是相关的。你知道吗
解决方法是避免
evalf(subs=dict)
构造(是否有文档记录?)。按自然顺序使用方法:替换,然后评估,给出正确的结果:相关问题 更多 >
编程相关推荐