如何在表达式中用理性替换浮点数?

时间:2014-01-08 19:47:31

标签: python sympy

我有一个来自同情心计算的表达式:

sqrt(pi)*(0.333333333333333*a + 0.333333333333333*b - 2.66666666666667*c**2)

其中a,b,c是符号,并且想要解析它以便浮点数被替换为如

中的有理数
sqrt(pi)*(1/3*a + 1/3*b - 8/3*c**2)

我知道如何手动完成,

In[24] Rational(str(0.333333333333333)).limit_denominator(1000)

Out[24]: 1/3

但是我不太清楚如何解析原子并只选择那些浮子,并用有理数近似代替。

在表达式中进行这些替换的最明智的方法是什么?

2 个答案:

答案 0 :(得分:7)

使用nsimplify

>>> print(nsimplify(sqrt(pi)*(0.333333333333333*a + 0.333333333333333*b - 2.66666666666667*c**2)))
sqrt(pi)*(a/3 + b/3 - 8*c**2/3)

答案 1 :(得分:1)

经过一番摆弄之后,我想我已经找到了办法,但我不确定它是否会涵盖所有角落案例。无论如何,这是。有任何改进建议吗?

import sympy
def rationalize_coeffs(expr):
    for i in expr.atoms(sympy.Float):
        r = sympy.Rational(str(i)).limit_denominator(1000)
        expr = expr.subs(i, str(r.p)+'/'+str(r.q))
    return expr    

if __name__=='__main__':
    # given a sympy expression expr
    x,y,z = sympy.symbols('x y z')
    # expr_orig = 2/57.*x + 3./4.*y + 3./4.*z
    expr = 0.0350877192982456*x + 0.75*y + 0.75*z

    print rationalize_coeffs(expr)