def _real_to_rational(expr, tolerance=None):
"""
Replace all reals in expr with rationals.
>>> from sympy import nsimplify
>>> from sympy.abc import x
>>> nsimplify(.76 + .1*x**.5, rational=True)
sqrt(x)/10 + 19/25
"""
p = expr
reps = {}
reduce_num = None
if tolerance is not None and tolerance < 1:
reduce_num = ceiling(1/tolerance)
for float in p.atoms(C.Float):
key = float
if reduce_num is not None:
r = Rational(float).limit_denominator(reduce_num)
elif (tolerance is not None and tolerance >= 1 and
float.is_Integer is False):
r = Rational(tolerance*round(float/tolerance)
).limit_denominator(int(tolerance))
else:
r = nsimplify(float, rational=False)
# e.g. log(3).n() -> log(3) instead of a Rational
if not r.is_Rational:
if float < 0:
float = -float
d = Pow(10, int((mpmath.log(float)/mpmath.log(10))))
r = -Rational(str(float/d))*d
elif float > 0:
d = Pow(10, int((mpmath.log(float)/mpmath.log(10))))
r = Rational(str(float/d))*d
else:
r = Integer(0)
reps[key] = r
return p.subs(reps, simultaneous=True)
评论列表
文章目录