Хранение дробей как Rational Python
Как проект, я создаю Rational Class с нуля, который может принимать в качестве входных данных две дроби и хранить упрощенную дробь. Однако, когда я пытаюсь ввести две дроби, кажется, что неявно используется целочисленное деление, поэтому я не могу сохранить / манипулировать дробью вообще. Я неправильно подхожу к проблеме? Где ошибка?
Пример: Rational(3/2,9/2) возвращает (1,4), а не (1/3).
def gcd(numerator,denominator):
if numerator < 0:
absNum = -numerator
elif denominator < 0:
absDen = -denominator
else:
absNum = numerator
absDen = denominator
while absNum != absDen:
if absNum > absDen:
absNum = absNum - absDen
elif absDen >= absNum:
absDen = absDen - absNum
return(absNum)
class Rational:
def __init__(self,numerator=0,denominator=1):
self.numerator = numerator
self.denominator = denominator
if denominator == 0:
raise ZeroDivisionError("Error: cannot store number with 0 in denominator.")
elif denominator < 0:
if numerator < 0:
self.denominator = -denominator
self.numerator = -numerator
else:
self.numerator = numerator
self.denominator = -denominator
if numerator != 0:
com = gcd(numerator,denominator)
numerator = numerator/com
denominator = denominator/com
self.numerator = numerator
self.denominator = denominator
Rational(5/3,8/3)
Возвращает (1,2) вместо (5,8), как и должно быть. РЕДАКТИРОВАТЬ: Вторая половина: я хочу иметь возможность ввести Rational(Rational(5/3),Rational(8/3)) с (5,8) результат. Это кажется немного отличается от вышеупомянутого.
2 ответа
from __future__ import division
исправит проблему деления.
Примечание: если вы хотите, чтобы ваши рациональные значения были сохранены точно, вы должны убедиться, что числитель и знаменатель хранятся в виде целых чисел. Если я правильно читаю, ваша функция gcd не будет работать с плавающей точкой.
Чтобы решить эту проблему, вы можете сделать что-то вроде:
def __init__(self, num, den):
num1, den1 = float(num).as_integer_ratio()
den2, num2 = float(den).as_integer_ratio()
self.numerator = num1 * num2
self.denominator = den1 * den2
...
Это не хранилище переменной, а выражение, создающее экземпляр вашего класса. Если вы используете два целых числа, оно неявно будет использовать целочисленное деление. Вы должны использовать дроби или использовать функцию float ().
my_rational = Rational (3,0/2,9,0 / 2)
my_other_rational = Rational (float (3) / 2, float (9) / 2)
Редактировать: в Python 3.x это больше не так. Смотрите: http://www.python.org/dev/peps/pep-0238/