Python中的分数除法错误
我正在做一个关于算法的教程
其中一个练习是创建一个分数类,这个类可以接受负数的分母,并且仍然能正确显示结果。不过,当我进行除法运算时,输出的结果还是负数:
class Fraction:
def __init__(self, num, denom):
if isinstance(num, int) or isinstance(denom, int):
common = gcd(num, abs(denom))
self._num = num//common
self._denom = abs(denom)//common
else:
raise TypeError
def __str__(self):
return "%d / %d" % (self._num, self._denom)
def __mul__(self, other):
denum = self._num * other._num
div = self._denom * other._denom
return Fraction(denum, div)
def __truediv__(self, other):
temp_fraction = Fraction(other._denom, other._num)
return self.__mul__(temp_fraction)
def gcd(a, b):
while(b):
a, b = b, a%b
return a
if __name__ == '__main__':
print(Fraction(-4, -5) / Fraction(-1, -2))
print(Fraction(-4, 5) / Fraction(-1, 2))
# Both output -8 / 5, should be 8 / 5
有人能告诉我我哪里出错了吗?
编辑 我已经修正了我的代码,并且重新写了一些错误的测试。现在所有测试都通过了!
完整代码:
from fractions import gcd
class Fraction:
"""
Checking if instantiating a fraction works
>>> print(Fraction(1, 2))
1 / 2
>>> print(Fraction(-1, 2))
-1 / 2
>>> print(Fraction('Foo', 'Bar'))
Traceback (most recent call last):
TypeError
Adding a fraction to another fraction
>>> print(Fraction(1, 2) + Fraction(1, 4))
3 / 4
>>> print(Fraction(-1, 2) + Fraction(2, 2))
1 / 2
>>> print(Fraction(-1, 5) + Fraction(-1, 5))
-2 / 5
>>> print(Fraction(-1, -5) + Fraction(-1, -5))
2 / 5
Substracting a fraction from another
>>> print(Fraction(3, 4) - Fraction(1, 4))
1 / 2
>>> print(Fraction(-1, 2) - Fraction(1, 4))
-3 / 4
>>> print(Fraction(-2, 10) - Fraction(-1, 10))
-1 / 10
>>> print(Fraction(-2, -10) - Fraction(-1, -10))
1 / 10
Multiplying 2 fractions
>>> print(Fraction(1, 5) * Fraction(1, 2))
1 / 10
>>> print(Fraction(-1, 2) * Fraction(1, 4))
-1 / 8
>>> print(Fraction(-1, 2) * Fraction(-1, 8))
1 / 16
>>> print(Fraction(-1, -2) * Fraction(-1, -8))
1 / 16
Dividing 2 fractions
>>> print(Fraction(1, 4) / Fraction(1, 2))
1 / 2
>>> print(Fraction(-1, 2) / Fraction(1, 15))
-15 / 2
>>> print(Fraction(-4, 5) / Fraction(-1, 2))
8 / 5
>>> print(Fraction(-4, -5) / Fraction(-1, -2))
8 / 5
Equality between fractions
>>> print(Fraction(1, 2) == Fraction(2, 4))
True
>>> print(Fraction(1, 2) == Fraction(1, 3))
False
>>> print(Fraction(-2, 4) == Fraction(-1, 2))
True
>>> print(Fraction(-2, -4) == Fraction(-1, -2))
True
Non-equality between fractions
>>> print(Fraction(1, 2) != Fraction(64, 128))
False
>>> print(Fraction(1, 4) != Fraction(999, 4000))
True
>>> print(Fraction(-3, 4) != Fraction(-3, 5))
True
>>> print(Fraction(-3, -4) != Fraction(-3, -5))
True
Larger size difference between fractions
>>> print(Fraction(1, 2) > Fraction(857, 1713))
False
>>> print(Fraction(1, 2) > Fraction(857, 1715))
True
>>> print(Fraction(1, 338) >= Fraction(2, 676))
True
>>> print(Fraction(-2, 5) > Fraction(-1, 5))
False
>>> print(Fraction(-2, -5) > Fraction(-1, -5))
True
Smaller size difference between fractions
>>> print(Fraction(1, 2) < Fraction(857, 1713))
True
>>> print(Fraction(1, 2) < Fraction(857, 1715))
False
>>> print(Fraction(1, 338) <= Fraction(2, 676))
True
>>> print(Fraction(-3, 7) < Fraction(-6, 7))
False
>>> print(Fraction(-3, -7) < Fraction(-6, -7))
True
"""
def __init__(self, num, denom):
if isinstance(num, int) and isinstance(denom, int):
common = gcd(num, denom)
self._num = num//common
self._denom = denom//common
else:
raise TypeError
def __str__(self):
return "%d / %d" % (self._num, self._denom)
def __add__(self, other):
denum = (self._num * other.get_denom()) + (other.get_num() * self._denom)
div = (self._denom * other.get_denom())
return Fraction(denum, div)
def __sub__(self, other):
denum = (self._num * other.get_denom()) - (other.get_num() * self._denom)
div = (self._denom * other.get_denom())
return Fraction(denum, div)
def __mul__(self, other):
denum = self._num * other.get_num()
div = self._denom * other.get_denom()
return Fraction(denum, div)
def __truediv__(self, other):
temp_fraction = Fraction(other.get_denom(), other.get_num())
return self.__mul__(temp_fraction)
def eq_denum(self, other):
first = self._num * other.get_denom()
last = other.get_num() * self._denom
return first, last
def __eq__(self, other):
first, last = self.eq_denum(other)
return first == last
def __ne__(self, other):
first, last = self.eq_denum(other)
return first != last
def __gt__(self, other):
first, last = self.eq_denum(other)
return first > last
def __ge__(self, other):
first, last = self.eq_denum(other)
return first >= last
def __lt__(self, other):
first, last = self.eq_denum(other)
return first < last
def __le__(self, other):
first, last = self.eq_denum(other)
return first <= last
def get_num(self):
return self._num
def get_denom(self):
return self._denom
if __name__ == '__main__':
import doctest
doctest.testmod()
2 个回答
-2
只需要把__str__改成:
return "%d / %d" % (abs(self._num), abs(self._denom))
1
问题不在于除法,而是在于你在 __init__
方法中如何使用你的 gcd
函数。
看起来你只需要在创建分数的时候 去掉 所有的 abs
。这样的话,如果 denom
是负数,gcd
也会是负数,这样就能得到你想要的效果。
if isinstance(num, int) and isinstance(denom, int):
common = gcd(num, denom)
self._num = num//common
self._denom = denom//common
这里有一些例子:
# with abs # without abs
print(Fraction( 4, 6)) # 2/3 2/3
print(Fraction( 4, -6)) # 2/3 -2/3
print(Fraction(-4, 6)) # -2/3 -2/3
print(Fraction(-4, -6)) # -2/3 2/3
另外,要注意 两个 数字都应该是整数,而不仅仅是其中一个(用 and
来判断)。