Статьи

Учебные материалы по языку Python — от основ до продвинутых тем

Decimal и Fraction

Страница 18 из 34 · 2026-10-26 · 4 мин чтения

Зачем нужны

float хранит числа в двоичном виде, поэтому не подходит для денег и точных расчётов:

print(0.1 + 0.2)print(sum([0.1] * 10) == 1.0)

Модуль decimal реализует десятичную арифметику с заданной точностью, fractions — точные рациональные числа.

Decimal

from decimal import Decimala = Decimal("0.1")b = Decimal("0.2")print(a + b)print(a + b == Decimal("0.3"))print(Decimal("1.10") + Decimal("2.205"))

Создавайте Decimal из строк. Создание из float сохраняет неточность двоичного представления:

print(Decimal(0.1))print(Decimal("0.1"))print(Decimal.from_float(0.5))

Арифметика

x = Decimal("10")y = Decimal("3")print(x / y)print(x // y)print(x % y)print(x ** 2)print(-x)print(abs(Decimal("-2.5")))print(x + 1)

Смешивать Decimal с float нельзя — будет TypeError. С целыми числами смешивать можно.

Методы Decimal

МетодОписание
quantize(exp, rounding=None)Округление до заданного порядка
to_integral_value()Округление до целого
sqrt(), exp(), ln(), log10()Математические функции
normalize()Убирает хвостовые нули
as_tuple()Знак, цифры, показатель степени
is_nan(), is_infinite(), is_finite(), is_zero(), is_signed()Проверки
copy_abs(), copy_negate(), copy_sign(other)Копирование со знаком
compare(other)Сравнение с результатом Decimal
as_integer_ratio()Дробь
adjusted()Показатель старшей цифры
fma(a, b)Умножение и сложение за одну операцию
max(other), min(other)Максимум и минимум

Округление

from decimal import Decimal, ROUND_HALF_UP, ROUND_DOWN, ROUND_HALF_EVENprice = Decimal("2.675")print(price.quantize(Decimal("0.01")))print(price.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))print(price.quantize(Decimal("0.01"), rounding=ROUND_DOWN))print(Decimal("2.5").quantize(Decimal("1"), rounding=ROUND_HALF_EVEN))
РежимОписание
ROUND_HALF_EVENК ближайшему чётному (по умолчанию)
ROUND_HALF_UPПоловина от нуля
ROUND_HALF_DOWNПоловина к нулю
ROUND_UPОт нуля
ROUND_DOWNК нулю
ROUND_CEILINGК плюс бесконечности
ROUND_FLOORК минус бесконечности
ROUND_05UPОт нуля, если последняя цифра 0 или 5

Контекст

from decimal import Decimal, getcontext, localcontextprint(getcontext().prec)getcontext().prec = 10print(Decimal(1) / Decimal(7))with localcontext() as ctx:    ctx.prec = 50    print(Decimal(1) / Decimal(7))print(Decimal(1) / Decimal(7))

Контекст хранит точность (prec), режим округления (rounding), границы показателя и управление сигналами (traps). Точность по умолчанию — 28 знаков.

Пример: сумма заказа

from decimal import Decimal, ROUND_HALF_UPitems = [("Книга", Decimal("19.99"), 2), ("Ручка", Decimal("1.50"), 5)]subtotal = sum(price * qty for _, price, qty in items)tax = (subtotal * Decimal("0.20")).quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)total = subtotal + taxprint(subtotal, tax, total)

Fraction

Fraction хранит числитель и знаменатель в виде целых чисел и всегда приводит дробь к несократимому виду:

from fractions import Fractiona = Fraction(1, 3)b = Fraction(2, 6)c = Fraction("3/4")d = Fraction("0.125")e = Fraction(0.5)print(a == b)print(a + c)print(c * d)print(a / c)print(c ** 2)print(Fraction(3, 1))

Атрибуты и методы Fraction

ЭлементОписание
numerator, denominatorЧислитель и знаменатель
limit_denominator(max)Ближайшая дробь с ограниченным знаменателем
as_integer_ratio()Пара (числитель, знаменатель)
from_float(x), from_decimal(d)Классовые методы
is_integer()Равна ли целому (Python 3.12+)
floor, ceil, round, truncЧерез math и round
import mathfrom fractions import Fractionf = Fraction(7, 2)print(f.numerator, f.denominator)print(math.floor(f), math.ceil(f), round(f))print(float(f))print(Fraction(0.1).limit_denominator(100))print(Fraction(3.14159).limit_denominator(1000))

Fraction совместим с Decimal и int в арифметике (с Decimal — нужно явное преобразование), а при сложении с float результат становится float.

Сравнение числовых типов

ТипТочностьСкоростьПрименение
intТочныйВысокаяЦелые значения
float≈ 15–17 цифрОчень высокаяНаучные расчёты, графика
DecimalЗаданная десятичнаяНизкаяДеньги, бухгалтерия
FractionТочная рациональнаяНизкаяТочные дроби, математика
complexКак floatВысокаяСигналы, физика

Модуль numbers описывает иерархию числовых типов:

import numbersfrom decimal import Decimalfrom fractions import Fractionprint(isinstance(1, numbers.Integral))print(isinstance(Fraction(1, 2), numbers.Rational))print(isinstance(1.5, numbers.Real))print(isinstance(1j, numbers.Complex))print(isinstance(Decimal("1"), numbers.Real))

Результат: True, True, True, True, False.

Задания

  1. Посчитайте сумму 0.1 сто раз через float и Decimal, сравните результаты.
  2. Реализуйте функцию округления цены до копеек с режимом «банковского» округления и «школьного».
  3. Преобразуйте десятичную периодическую дробь 0.(3) в Fraction и сложите с 1/6.