Одно дробное число в два целых
Я реализовал класс Fraction, оригинальный модуль может принять число типа float и превратить его в два целых числа, знаменатель и числитель.
Моя версия так не умеет, как такое реализовать, какой алгоритм использовать
Вод код:
def NOD(a, b):
while a and b:
if a < b:
b %= a
else:
a %= b
return max(a, b)
def NOK(a, b):
return a * b / NOD(a, b)
class fraction():
def __init__(self, x, y = 1):
self.x, self.y = x, y
def __repr__(self):
return f"{self.x} {self.y}"
def __add__(self, other):
n = NOK(self.y, other.y)
d1, d2 = n / other.y, n / self.y
return fraction(self.x * d1 + other.x * d2, n)
Ответы (3 шт):
ну во-первых можно сделать просто
numerator = int(value * 100)
denumerator = 100
и потом привести дробь к несократимой
gcd = math.gcd(numerator, denumerator);
numenator //= gcd
denumenator //= gcd
чем больше точность нужна, тем больше делитель нужен
В c++ я бы просто float разобрал бы вытащив мантиссу в виде целого числа и потом бы делил на экспоненту в виде целого числа
А в питоне по идее с их неограниченным int можно просто взять 10**n превышающей размер float (там вроде как двойная точность у питоновских вещественных)
P.S.
по идее любое вещественное число можно превратить в непрерывную дробь
и если уж определена операция сложения дробей, то в итоге можно получить и нужную простую дробь наиболее близкую к нужному вещественному числу
этот подход хотя и довольной медленный (несколько операций будет), но наверное и самый точный
Инструкции для точного перевода float в дробь:
Конвертируйте
floatна точное шестнадцатеричное число в виде строки с применением метода.hex().Пример:
>>> x = -18.25 >>> x.hex() '-0x1.2400000000000p+4'Вы получите всегда один и тот же формат, с точкой после целой части, с 13-ми шестнадцатеричными цифрами и экспонентом после буквы
p.Эта запись значит
-(1 + 2/16 + 4/16**2 + ... + 0/16**13) * 2**4или (после приведения к общему знаменателю)
-(1*16**13 + 2*16**12 + 4*16**11 + ... + 0) / 16**13 * 2**4или (после умножения дробей)
-(1*16**13 + 2*16**12 + 4*16**11 + ... + 0) * 2**4 / 16**13Теперь ясно, что
- числителем будет
-(1*16**13 + 2*16**12 + 4*16**11 + ... + 0) * 2**4, - знаменателем будет
16**13(всегда).
- числителем будет
float, int и ещё некоторые типы имеют метод as_integer_ratio, который возвращает кортеж из двух элементов, числителя и знаменателя.
Пример
print((15).as_integer_ratio())
print((0.76).as_integer_ratio())