Др

Дроби у Python

{one: "1 вправа", few: "%{count} вправи", many: "%{count} вправ", other: "%{count} вправи"}

Про концепцію Дроби

Модуль fractions дає змогу створювати rational numbers і працювати з ними: це дроби, у яких ціле число в чисельнику ділиться на ціле число в знаменнику.

Наприклад, ми можемо зберегти 2/3 як точний дріб, а не як наближене значення float 0.6666...

Створення дробів

На відміну від чисел int, float і complex, дроби не мають літеральної форми. Утім, конструктор дробів доволі гнучкий.

Найочевидніше: він може приймати два цілі числа. Спільні множники автоматично скорочуються, і дріб перетворюється на свій «найпростіший вигляд» (найменші цілі числа, які точно представляють дріб):

>>> from fractions import Fraction

>>> f1 = Fraction(2, 3) # 2/3
>>> f1
Fraction(2, 3)

>>> f2 = Fraction(6, 9)
>>> f2
Fraction(2, 3)  # automatically simplified

>>> f1 == f2
True

Конструктор дробів також уміє розбирати рядкове представлення:

>>> f3 = Fraction('2/3')
>>> f3
Fraction(2, 3)

Він також може працювати з параметрами float, але тут можливі проблеми через наближену природу внутрішнього подання десяткового значення у двійковій формі. Докладніше про цю проблему подання можна прочитати на сайті 0.30000000000000004 і в розділі Арифметика з плаваючою комою: проблеми та обмеження документації Python.

Для надійнішого результату, коли ми використовуємо float разом із дробами, є метод <fraction>.limit_denominator().

.limit_denominator() може приймати цілочисельний параметр, якщо у нас є конкретні вимоги, але навіть типове значення (max_denominator=1000000) може чудово працювати й давати прийнятне просте наближення.

>>> Fraction(1.2)
Fraction(5404319552844595, 4503599627370496)

>>> Fraction(1.2).limit_denominator()
Fraction(6, 5)

Арифметика з дробами

Звичайні arithmetic operators + - * / ** працюють із дробами так само, як і з іншими числовими типами.

До виразу можна включати цілі числа й інші Fraction, і результат буде Fraction. Якщо у виразі є float, результат теж буде float, із можливою втратою точності.

>>> Fraction(2, 3) + Fraction(1, 4) # addition
Fraction(11, 12)

>>> Fraction(2, 3) * Fraction(6, 5) # multiply fractions
Fraction(4, 5)

>>> Fraction(2, 3) * 6 / 5 # fraction with integers
Fraction(4, 5)

>>> Fraction(2, 3) * 1.2  # fraction with float -> float
0.7999999999999999

>>> Fraction(2, 3) ** 2  # exponentiation with integer
Fraction(4, 9)

Перетворення на дроби і назад

Дроби чудово зберігають точність під час проміжних обчислень, але для остаточних вихідних даних вони можуть не підійти.

Можна отримати чисельник і знаменник окремо або як кортеж (tuples буде розглянуто в пізнішій концепції):

>>> Fraction(2, 3).numerator
2
>>> Fraction(2, 3).denominator
3
>>> Fraction(2, 3).as_integer_ratio()
(2, 3)

Різні стандартні числові функції Python також дають той результат, який ми могли б очікувати від роботи з типами int і float:

>>> round(Fraction(11, 3))
4

>>> from math import floor, ceil
>>> floor(Fraction(11, 3))
3
>>> ceil(Fraction(11, 3))
4

>>> float(Fraction(11, 3))
3.6666666666666665
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці