Хранение дробей как 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/

Другие вопросы по тегам