为了提高精度,我自定义了一个MyFloat类型
from sympy.core.numbers import *
from sympy.core.numbers import _sympifyit, _as_integer_ratio, _errdict, _sympify
class MyFloat(Float):
#is_rational = is_Rational = True
#is_irrational = False
def __new__(cls, arg):
if isinstance(Rational(arg), Integer):
return Rational(arg)
arg = str(arg).replace(' ', '').strip('0')
if arg[0] == '.': arg = f'0{arg}'
prec = len(arg.replace('.', ''))
return super().__new__(cls, arg, prec)
def __init__(self, arg):
self.content = str(arg)
def __str__(self):
return self.content
@_sympifyit('other', NotImplemented)
def __add__(self, other):
if isinstance(other, Number) and global_parameters.evaluate:
if isinstance(other, Rational) and other.q != 1:
return Rational(str(self)) + other
a1 = str(self).split('.')
a2 = str(Float(other)).split('.')
length = max(len(a1[1]), len(a2[1]))
a1[1] = a1[1].ljust(length, '0')
a2[1] = a2[1].ljust(length, '0')
result = str(int(''.join(a1)) + int(''.join(a2)))
return MyFloat(f'{result[:-length]}.{result[-length:]}')
return Number.__add__(self, other)
@_sympifyit('other', NotImplemented)
def __sub__(self, other):
if isinstance(other, Number) and global_parameters.evaluate:
if isinstance(other, Rational) and other.q != 1:
return Rational(str(self)) - other
a1 = str(self).split('.')
a2 = str(Float(other)).split('.')
length = max(len(a1[1]), len(a2[1]))
a1[1] = a1[1].ljust(length, '0')
a2[1] = a2[1].ljust(length, '0')
result = str(int(''.join(a1)) - int(''.join(a2)))
return MyFloat(f'{result[:-length]}.{result[-length:]}')
return Number.__sub__(self, other)
@_sympifyit('other', NotImplemented)
def __mul__(self, other):
if isinstance(other, Number) and global_parameters.evaluate:
if isinstance(other, Rational) and other.q != 1:
return Rational(str(self)) * other
a1 = str(self).rstrip('0').split('.')
a2 = str(Float(other)).rstrip('0').split('.')
length = len(a1[1]) + len(a2[1])
result = str(int(''.join(a1)) * int(''.join(a2)))
return MyFloat(f'{result[:-length]}.{result[-length:]}')
return Number.__mul__(self, other)
@_sympifyit('other', NotImplemented)
def __truediv__(self, other):
if isinstance(other, Number) and other != 0 and global_parameters.evaluate:
return Rational(str(self))/Rational(str(other))
return Number.__truediv__(self, other)
@_sympifyit('other', NotImplemented)
def __mod__(self, other):
if isinstance(other, Rational) and other.q != 1 and global_parameters.evaluate:
# calculate mod with Rationals, *then* round the result
return Rational(str(self)) % other
if isinstance(other, Number) and global_parameters.evaluate:
r = Rational(str(self)) // Rational(str(other))
return self - MyFloat(str(other))*r
return Number.__mod__(self, other)
def _latex(self, printer):
return str(self).rstrip('0')
但是下面的代码我期望输出[45/23],我想知道出了什么问题以及如何解决(这里的MyFloat不能用Rational代替)
>>> solve(x*MyFloat('2.3')-MyFloat('4.5')) # solve和x已经在sympy和sympy.abc中导入
[1.95652173913043]