Модуль math: математические функции Python
Модуль math в Python содержит математические функции и константы для работы с числами: корни, логарифмы, тригонометрию, округление, факториал и комбинаторику. Из статьи вы узнаете, как подключить модуль, чем его функции отличаются от встроенных операторов и какие ошибки чаще всего возникают при вычислениях с дробными числами.

Содержание статьи
Подключение модуля и константы
Модуль входит в стандартную библиотеку, устанавливать его не нужно. Обычно пишут import math и обращаются к функциям через точку. Если в коде нужны одна-две функции, их можно импортировать по имени, тогда префикс не требуется. Подробнее о вариантах импорта в статье про импорт библиотек.
import math
from math import sqrt, pi
print(math.sqrt(16)) # 4.0
print(sqrt(2)) # 1.4142135623730951
print(pi) # 3.141592653589793Кроме функций, в модуле есть пять констант. Они хранятся как числа float с точностью около 15-17 значащих цифр.
| Константа | Значение | Назначение |
|---|---|---|
math.pi | 3.141592653589793 | Число пи, отношение длины окружности к диаметру |
math.e | 2.718281828459045 | Основание натурального логарифма |
math.tau | 6.283185307179586 | 2 пи, полный оборот в радианах |
math.inf | inf | Положительная бесконечность, больше любого числа |
math.nan | nan | Не число, результат неопределенной операции |
math.inf удобно брать как стартовое значение при поиске минимума, а -math.inf при поиске максимума. С math.nan есть особенность: это значение не равно даже самому себе, поэтому проверять его нужно функцией math.isnan(), а не через ==.
Округление и отбрасывание дробной части
Для округления в модуле три функции, и все они возвращают int. Разница видна на отрицательных числах, где легко ошибиться.
| Функция | Что делает | 2.7 | -2.7 |
|---|---|---|---|
math.floor(x) | Округляет вниз, к меньшему целому | 2 | -3 |
math.ceil(x) | Округляет вверх, к большему целому | 3 | -2 |
math.trunc(x) | Отбрасывает дробную часть, к нулю | 2 | -2 |
round(x) | Встроенная, к ближайшему целому | 3 | -3 |
Типичная задача на ceil: сколько страниц нужно, чтобы показать 103 товара по 20 на странице. Обычное деление дает 5.15, а страниц нужно 6.
import math
items, per_page = 103, 20
print(math.ceil(items / per_page)) # 6
print(math.floor(-2.5), math.trunc(-2.5)) # -3 -2Встроенная round() использует банковское округление: половина округляется к ближайшему четному, поэтому round(2.5) дает 2. Если нужно округление до заданного числа знаков или по школьному правилу, смотрите разбор в статье об округлении чисел в Python.
Степени, корни и логарифмы
Функция math.sqrt(x) возвращает квадратный корень в виде float. Для целых чисел есть math.isqrt(n): она возвращает целую часть корня как int и не теряет точность на очень больших числах. С версии 3.11 появилась math.cbrt(x) для кубического корня.
import math
print(math.sqrt(26)) # 5.0990195135927845
print(math.isqrt(26)) # 5
print(math.cbrt(27)) # 3.0 (Python 3.11+)
print(math.pow(2, 10)) # 1024.0
print(2 ** 10) # 1024math.pow() всегда приводит аргументы к float и возвращает float. Оператор ** и встроенная pow() для целых чисел возвращают точный int любой длины, поэтому 10 ** 400 считается, а math.pow(10, 400) вызывает OverflowError. Для целочисленных степеней лучше использовать **.
Логарифмы считаются функцией math.log(x, base). Без второго аргумента она дает натуральный логарифм. Для оснований 2 и 10 есть отдельные функции log2() и log10(), они точнее, чем log(x, 2). Обратная операция к натуральному логарифму - math.exp(x).
print(math.log(math.e)) # 1.0
print(math.log2(1024)) # 10.0
print(math.log10(0.001)) # -3.0
print(math.log(81, 3)) # 4.0
print(math.exp(2)) # 7.38905609893065Аргумент вне области определения вызывает ValueError с текстом math domain error. Это бывает при math.sqrt(-1), math.log(0) или math.acos(2). Для корней из отрицательных чисел используют модуль cmath, он работает с комплексными числами: cmath.sqrt(-4) вернет 2j.
Тригонометрия и геометрия
Тригонометрические функции sin, cos, tan принимают угол в радианах. Угол в градусах сначала переводят функцией math.radians(), обратный перевод делает math.degrees(). Обратные функции asin, acos, atan возвращают результат тоже в радианах.
import math
angle = math.radians(30)
print(round(math.sin(angle), 4)) # 0.5
print(math.degrees(math.pi / 4)) # 45.0
print(math.sin(math.pi)) # 1.2246467991473532e-16, а не 0Последняя строка показывает погрешность float: синус пи должен быть нулем, но math.pi хранится приближенно. Результаты таких вычислений округляют или сравнивают через math.isclose().
Для геометрии пригодятся три функции. math.hypot(x, y) считает длину гипотенузы, math.dist(p, q) - евклидово расстояние между двумя точками любой размерности, math.atan2(y, x) - угол точки относительно начала координат с учетом четверти.
print(math.hypot(3, 4)) # 5.0
print(math.dist((1, 2), (4, 6))) # 5.0
print(math.degrees(math.atan2(-1, -1))) # -135.0Целые числа и комбинаторика
Этот блок функций работает только с целыми числами. math.factorial(n) вычисляет n!, а с Python 3.10 при передаче float вроде 5.0 выдает TypeError. math.gcd() находит наибольший общий делитель, math.lcm() наименьшее общее кратное. С версии 3.9 обе функции принимают любое количество аргументов.
import math
print(math.factorial(5)) # 120
print(math.gcd(24, 36, 60)) # 12
print(math.lcm(4, 6, 10)) # 60
print(math.comb(5, 2)) # 10
print(math.perm(5, 2)) # 20math.comb(n, k) возвращает число сочетаний: сколькими способами выбрать k элементов из n без учета порядка. math.perm(n, k) считает размещения, где порядок важен. Например, выбрать двух дежурных из пяти человек можно 10 способами, а назначить из пяти человек старосту и заместителя 20 способами.
Для последовательностей чисел есть math.prod(), произведение элементов, и math.fsum(), сумма без накопления ошибки округления. Встроенная sum() складывает float по очереди, и погрешность растет с каждым шагом.
nums = [0.1] * 10
print(sum(nums)) # 0.9999999999999999
print(math.fsum(nums)) # 1.0
print(math.prod([2, 3, 4])) # 24Сравнение дробных чисел и проверки
Числа float хранятся в двоичном виде, и многие десятичные дроби в нем не представимы точно. Поэтому 0.1 + 0.2 == 0.3 дает False. Для сравнения используют math.isclose(a, b), которая проверяет близость с относительной погрешностью rel_tol=1e-09 по умолчанию.
import math
print(0.1 + 0.2 == 0.3) # False
print(math.isclose(0.1 + 0.2, 0.3)) # True
print(math.isclose(1e-12, 0)) # False
print(math.isclose(1e-12, 0, abs_tol=1e-9)) # TrueПри сравнении с нулем относительная погрешность не работает: любое ненулевое число относительно нуля бесконечно далеко. В этом случае задают абсолютный допуск abs_tol, как в последней строке примера.
Функции math.isnan(), math.isinf() и math.isfinite() проверяют специальные значения. Они полезны при обработке данных, где после деления или чтения файла могут появиться nan и бесконечности. Полный список функций с описанием есть в официальной документации.
Частые вопросы
Ответы на вопросы, которые возникают при работе с модулем math.
Чем math.sqrt отличается от x ** 0.5?
Результат для положительных чисел совпадает, оба возвращают float. Разница в отрицательных числах: math.sqrt(-4) вызывает ValueError, а (-4) ** 0.5 молча возвращает комплексное число. Явная ошибка помогает раньше заметить некорректные данные.
Работает ли math со списками и массивами?
Нет, функции модуля принимают одно число. Чтобы применить функцию ко всему списку, используют генератор списка: [math.sqrt(x) for x in data]. Для больших массивов быстрее NumPy, где np.sqrt() обрабатывает весь массив сразу.
Почему math.floor и math.ceil возвращают int, а sqrt float?
Округление по определению дает целое число, поэтому с Python 3 эти функции возвращают int. Корень, логарифм и тригонометрия в общем случае дробные, поэтому возвращают float даже для точных значений вроде math.sqrt(16).
Как вычислить среднее или медиану?
В math таких функций нет. Для статистики есть модуль statistics: statistics.mean(), statistics.median(), statistics.stdev(). Об основных числовых типах и операциях над ними рассказано в статье числа в Python 3.