Арифметика

Операции с дробями

Цели урока

  • Привести любые дроби к общему знаменателю через НОК
  • Складывать и вычитать дроби с разными знаменателями
  • Умножать дроби с предварительным сокращением
  • Делить дроби через переворот и умножение
  • Видеть связь школьной арифметики с PyTorch, A/B-тестами и Брезенхэмом

Предварительные знания

  • Понимание дроби как части целого (введение в дроби)
  • Знание таблицы умножения
  • Понятие НОК и НОД на интуитивном уровне

Каждая итерация обучения GPT-style модели в смешанной точности (FP16 forward, FP32 master weights) - это сложение тысяч градиентов-дробей с общим знаменателем размера батча. NVIDIA Apex (2018) и встроенный torch.cuda.amp ускорили обучение в 2-3 раза именно за счёт грамотной арифметики дробей с разной точностью.

  • **PyTorch gradient accumulation** - суммирование микро-батчей как дробей с общим знаменателем
  • **Bresenham line algorithm (1962)** - рисование линий на дисплее через целочисленную арифметику дробей dx/dy
  • **Audio sample-rate conversion 44.1 кГц -> 48 кГц** - ratio 147/160, ресемплинг через НОК частот
  • **A/B-тесты в Booking, Airbnb, GrowthBook** - lift = (variant/control) - 1, деление двух дробей-конверсий
  • **Cron и Kubernetes scheduler** - hyperperiod задач = НОК их периодов, точка синхронизации

Папирус Ринда и египетские дроби

Древние египтяне записывали все дроби как сумму единичных: 2/5 = 1/3 + 1/15. Папирус Ринда содержит 84 задачи на такие разложения. Эта идея вернулась в XX веке как алгоритм Фибоначчи-Сильвестра и применяется в современной криптографии при работе с непрерывными дробями для атак на RSA с малыми экспонентами.

Общий знаменатель

**cron-задачи на Linux-сервере, запущенные с периодами 1/3 и 1/4 часа, синхронизируются ровно раз в час - в момент НОК(3, 4) = 12 интервалов.** Тот же приём планировщики в Kubernetes и Airflow используют для расчёта rendezvous-окон. Сложение дробей и поиск общего расписания - одна и та же операция: чтобы говорить на одном языке, нужен **одинаковый знаменатель**. Третьи и четвёртые - это разные единицы, как метры и футы.

**Общий знаменатель** - число, делящееся на все знаменатели. Оптимальный выбор - **НОК** (наименьшее общее кратное), он же НОК. В планировщиках задач это называют hyperperiod: интервал, через который вся система возвращается в исходное расписание. Для 1/3 и 1/4: НОК(3, 4) = 12.

Ключевая идея: умножение числителя и знаменателя на одно и то же число не меняет значения. Это как ресемплинг массива - количество отсчётов растёт, а сигнал тот же. Именно так работает аудио sample-rate conversion с 44.1 кГц до 48 кГц: 44100/48000 = 147/160, и драйвер ищет НОК между двумя частотами, чтобы выстроить общую сетку семплов.

При приведении к общему знаменателю достаточно поменять только знаменатель

Числитель и знаменатель умножаются на один и тот же множитель

Дробь - это деление. 2/3 ≠ 2/15: одно равно 0.666…, другое 0.133…. Эквивалентность сохраняется только при умножении обеих частей на одинаковое число.

Чему равна дробь 2/3, приведённая к знаменателю 15?

Сложение и вычитание

Когда знаменатели одинаковые, сложение и вычитание сводятся к работе с числителями. Этот же приём лежит в основе **gradient accumulation в PyTorch**: при обучении больших моделей градиенты считаются по микро-батчам и суммируются как дроби с общим знаменателем (общим числом примеров) перед шагом оптимизатора.

**Kahan summation** - алгоритм компенсированного суммирования в численных библиотеках NumPy и BLAS. Когда складывается миллион дробных чисел разного порядка, ошибка округления накапливается. Kahan хранит "остаток" отдельно - буквально дробную часть, потерянную при сложении, - и добавляет её в следующий шаг. Та же идея, что и приведение к общему знаменателю: ничего не должно потеряться.

**Алгоритм сложения и вычитания:** 1. Привести к общему знаменателю. 2. Сложить или вычесть числители. 3. Знаменатель оставить. 4. Сократить, если возможно.

После сложения результат проверяется на сократимость: 4/8 сводится к 1/2. В производственном коде numerical libraries это шаг нормализации - тот же, что выполняет Python `Fraction` из модуля `fractions` через НОД числителя и знаменателя.

Чему равно 3/4 + 1/6?

Умножение дробей

**Maximum likelihood estimation в каждой ML-библиотеке начинается с произведения вероятностей: $P(x_1)\cdot P(x_2)\cdot \ldots \cdot P(x_n)$.** Каждая P - дробь от 0 до 1, и правило их умножения - то же самое правило, что для дробей в школе: числитель на числитель, знаменатель на знаменатель. Общий знаменатель не нужен - именно поэтому умножение проще сложения.

**Log-likelihood в практике:** прямое перемножение тысяч вероятностей даёт underflow в float64 уже на 700-800 множителях. Поэтому в TensorFlow и PyTorch вместо $\prod P_i$ считают $\sum \log P_i$ - произведение дробей превращается в сумму логарифмов. Структура та же, что и в школьной арифметике, только в другом базисе.

**Трюк: сокращение крест-накрест** Перед умножением можно сократить любой числитель с любым знаменателем: 6/15 × 5/8 = (6/2)/(15/5) × (5/5)/(8/2) = 3/3 × 1/4 = 1 × 1/4 = 1/4.

Умножение дроби на целое число: целое представляется как дробь со знаменателем 1. 3 × 2/5 = 3/1 × 2/5 = 6/5. Тот же приём в **алгоритме Брезенхэма для рисования линий**: вместо float-арифметики компьютер хранит ошибку как дробь с целым числителем и знаменателем (dx, dy), и умножения превращаются в целочисленные сложения.

Перед умножением дроби нужно привести к общему знаменателю

Общий знаменатель нужен только для сложения и вычитания

Умножение - это "часть от части", оно не требует одинаковых единиц. (a/b)(c/d) = (ac)/(bd) по определению. Принудительное приведение к общему знаменателю даст тот же ответ, но удвоит работу.

Чему равно 3/4 × 2/9?

Деление дробей

**A/B-тесты в продакшне сравнивают конверсии: 124/10000 против 137/10000. Чтобы получить relative lift, одна дробь делится на другую.** Деление дробей сводится к умножению по правилу: **делить на дробь = умножать на перевёрнутую** (обратную). Тот же приём в learning-rate scheduler: чтобы пересчитать шаг при изменении batch size c B1 на B2, lr делят на (B1/B2), что равносильно умножению на (B2/B1).

**Rate normalisation в продакшне:** во всех A/B-фреймворках (Optimizely, GrowthBook, in-house инструменты Booking.com) lift считается как (variant_rate / control_rate) - 1. Это деление двух дробей. Если variant даёт 137/10000, а control 124/10000, то lift = (137/124) - 1 ≈ 10.5%. Цена ошибки в этой формуле - неправильный продуктовый rollout.

**Мнемоника для деления:** "Первую оставить, знак поменять, вторую перевернуть". a/b / c/d = a/b × d/c.

Деление на дробь меньше единицы даёт результат **больше** делимого. Сколько половинок в целом? Две: 1 / 1/2 = 2. Тот же эффект в десятичных дробях: деление на 0.5 равносильно умножению на 2. Десятичные и обыкновенные - две формы одной и той же арифметики.

При делении дробей делим числители и знаменатели отдельно

Деление дроби равно умножению на обратную дробь

a/b / c/d не равно (a/c)/(b/d). Правильная формула: a/b / c/d = a/b × d/c = (a×d)/(b×c). Например 1/2 / 1/4 = 1/2 × 4/1 = 2.

Чему равно 5/6 / 2/3?

Ключевые идеи

  • Сложение и вычитание: общий знаменатель через НОК, потом - арифметика числителей
  • Умножение: числитель на числитель, знаменатель на знаменатель, общий знаменатель не нужен
  • Деление: переворот второй дроби и умножение
  • Сокращение результата до несократимой формы - стандартный финальный шаг
  • Эти же правила лежат в основе gradient accumulation, A/B-тестов и Брезенхэма

Связанные темы

Операции с дробями ведут в численные методы и вероятности.

  • Десятичные дроби — Альтернативная запись и floating-point арифметика
  • НОК и НОД — Инструмент общего знаменателя и сокращения
  • Пропорции — Равенство двух дробей как rate в A/B-тестах
  • Введение в вероятности — Произведение независимых событий повторяет умножение дробей

Вопросы для размышления

  • Почему для умножения дробей не нужен общий знаменатель, а для сложения - нужен?
  • Почему деление на дробь меньше единицы даёт результат больше делимого?
  • Какая связь между gradient accumulation в PyTorch и приведением дробей к общему знаменателю?

Связанные уроки

  • ar-06-fractions-intro — Базовое определение дроби и эквивалентность
  • ar-17-lcm — НОК - инструмент общего знаменателя
  • ar-08-decimals — Десятичная запись и floating-point
  • ar-10-proportions — Равенство дробей как пропорция и rate
  • prob-01-intro — Произведение независимых вероятностей повторяет умножение дробей
Операции с дробями

0

1

Войти