math - математические функции

Модуль math предоставляет доступ к математическим функциям и константам. Несмотря на то что числа комплексного типа (complex) являются встроенными, данный модуль их не поддерживает и всегда вызывает исключение при их использовании. Для того что бы использовать математические функции с комплексными числами обратитесь к модулю cmath.


Теория чисел

math.factorial(x)
Возвращает факториал указанного числа x.
>>> import math
>>> 
>>> math.factorial(5)
120
>>> 
>>> math.factorial(50)
30414093201713378043612608166064768844377641568960512000000000000

Данная функция всегда возвращает число типа int и поддерживает длинную арифметику, т.е. величина обрабатываемого числа x и возвращаемого результата ограничивается только мощностью вашего компьютера.

Если x не является целым числом (int) или если x является отрицательным, то будет вызвано исключение ValueError.

math.gcd(x)
Возвращает наибольший общий делитель (НОД) двух целых чисел a и b.
>>> import math
>>> 
>>> math.gcd(45, 81)
9

Если оба числа отличны от нуля, то будет возвращено число, которое всегда делит оба эти числа:

>>> math.gcd(3886, 9048)
58
>>> 
>>> 3886/58, 9048/58
(67.0, 156.0)

В случае если числа a и b являются взаимно простыми, то будет возвращена \(1\):

>>> math.gcd(17, 31)
1

Если одно из чисел равно нулю, то будет возвращено, другое, отличное от \(0\) число:

>>> math.gcd(17, 0)
17
>>> 
>>> math.gcd(0, 31)
31

Если оба числа равны \(0\), то функция вернет \(0\):

>>> math.gcd(0, 0)
0

Указанные числа должны быть целыми (тип int), но могут быть как положительными, так и отрицательными:

>>> math.gcd(-4, -8)
4
>>> 
>>> math.gcd(-4, -8.8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'float' object cannot be interpreted as an integer

Доступно в Python с версии 3.5.

math.frexp(x)
Возвращает кортеж из двух чисел (m, e) таких что x == m*2**e.
>>> import math
>>> 
>>> math.frexp(123)
(0.9609375, 7)
>>> 
>>> 0.9609375*2**7
123.0

Число m принадлежит к типу float и всегда является таким, что 0.5 <= abs(m) < 1, даже для тех случаев, когда значением x является произвольная степень двойки. Число e всегда целое (int):

>>> math.frexp(0.25)
(0.5, -1)
>>> 
>>> math.frexp(64)
(0.5, 7)

Если x равен \(0\), то будет возвращено (0.0, 0).

Чаще всего данная функция используется тогда, когда представление чисел типа float не должно зависеть от архитектуры используемой машины.

math.ldexp(x, i)
Возвращает x*2**i, т.е. является обратной к функции frexp().
>>> import math
>>> 
>>> math.ldexp(3, 4)
48.0
>>> 
>>> math.ldexp(0.125, 8)
32.0
math.fabs(x)
Возвращает абсолютное значение (модуль) числа x. Результат всегда типа float.
>>> import math
>>> 
>>> math.fabs(-3)
3.0
>>> 
>>> math.fabs(-3.14)
3.14

Данная функция в отличии от встроенной функции abs() не обрабатывает комплексные числа:

>>> math.fabs(1 + 1j)    # Приведет к ошибке
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't convert complex to float
>>> 
>>> 
>>> abs(1 + 1j)    # Ошибки не будет
1.4142135623730951
math.fmod(x)
Возвращает остаток от деления числа x на число y, вычисленный так, как это определено в библиотеке math языка C.
>>> import math
>>> 
>>> math.fmod(2.23, 0.2)
0.02999999999999986

Данная функция направлена на то, что бы результат был максимально приближен к значению x - n*y для некоторого целого числа n, что бы этот результат имел тот же знак, что и x, что бы разность x - n*y == abs(y).

Для чисел типа float данная функция является предпочтительнее чем команда x%y, которая в свою очередь является предпочтительной для чисел типа int, так как для некоторых случаев (например, при x = -1e-100 и 1e100) команда x%y может вообще выдать неправильный результат.

math.modf(x)
Возвращает кортеж из двух чисел (f, w) где f – дробная, а w – целая часть числа x. Результат всегда имеет тип float.
>>> import math
>>> 
>>> math.modf(3)
(0.0, 3.0)
>>> 
>>> math.modf(3.14)
(0.14000000000000012, 3.0)
math.fsum(iterable)
Возвращает точную сумму значений в итерируемом объекте iterable. Возвращаемый результат всегда типа float.
>>> import math
>>> 
>>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
0.9999999999999999
>>> 
>>> math.fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1])
1.0

Может показаться, что эта сумма будет точной всегда, но на самом деле это не так:

>>> math.fsum([0.3, 0.3, 0.3])
0.8999999999999999

Многое зависит от используемой платформы, точнее от сборки компилятора языка C, который используется на данной платформе. Если вам нужны точные арифметические операции с десятичными дробями, то воспользуйтесь модулем decimal.

math.copysign(x, y)
Возвращает число x со знаком числа y. Возвращаемый результат всегда типа float
>>> import math
>>> 
>>> math.copysign(14, -12)
-14.0
>>> 
>>> math.copysign(-14, 12)
14.0

Если используемой платформой поддерживаются нули со знаком, то знак второго аргумента так же будет копироваться:

>>> math.copysign(1, -0.0)
-1.0
>>> 
>>> math.copysign(0, -1)
-0.0
math.isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)
возвращает True если в пределах указанной точности, числа a и b близки настолько, что их можно считать равными.

Допустим у нас есть два числа и мы знаем, что по сути это одно и то же число, а все мизерные различия связаны с ошибками округления и двоичной арифметикой. Мы то понимаем что это как бы одно и то же число, а вот компьютер считает иначе:

>>> import math
>>> 
>>> x = 7
>>> 
>>> y = (7**0.5)**2
>>> y
7.000000000000001
>>> 
>>> x==y
False

Для таких ситуаций, в которых мы готовы считаться с некоторой погрешностью и подходит функция isclose():

>>> math.isclose(x, y)
True

Считать числа близкими или нет, определяют два параметра rel_tol и abs_tol().

Параметр rel_tol (relative tolerances) – это относительный допуск, определяемый как максимально допустимая разница между числами a и b относительно большего из них по модулю. По умолчанию, rel_tol = 1e-09, это гарантирует, что числа a и b будут одинаковы, в пределах 9 десятичных цифр. Что бы числа считались равными, если они, допустим, отличаются меньше чем на 0.1%, то достаточно установить rel_tol = 0.001, но в любом случае данный параметр, должен быть больше нуля:

>>> y
7.000000000000001
>>> 
>>> math.isclose(y, 6.999)
False
>>> 
>>> math.isclose(y, 6.999, rel_tol = 0.001)
True

Параметр abs_tol (absolute tolerances) – это минимальный абсолютный допуск, который определяет как сравнивать значения близкие к нулю. Данный параметр должен быть не меньше нуля:

>>> x = 2**(-1000)
>>> x
9.332636185032189e-302
>>> 
>>> y = 0.000000000001
>>> y
1e-12
>>> 
>>> math.isclose(x, y)
False
>>> 
>>> math.isclose(x, y, abs_tol = 10.e-14)
False
>>> math.isclose(x, y, abs_tol = 10.e-13)
True

Данная функция эквивалентна команде abs(a - b) <= max(rel_tol*max(abs(a), abs(b)), abs_tol). Значения inf, -inf считаются близкими только сами к себе, а NaN не является близким ни к одному значению, включая само NaN.


Округление чисел

math.trunc(x)
Отбрасывает дробную часть числа x.
>>> import math
>>> 
>>> math.trunc(3.14)
3
>>> 
>>> math.trunc(-3.14)
-3
math.floor(x)
Возвращает \(\lfloor x \rfloor \). Данную функцию так же называют "пол" числа x, т.е. такое число, которое является наибольшим целым числом меньшим или равным x.
>>> import math
>>> 
>>> math.floor(3.14)
3
>>> math.floor(-3.14)
-4
math.ceil(x)
Возвращает \(\lceil x \rceil \). Данную функцию так же называют "потолок" числа x, т.е. такое число, которое является наименьшим целым числом большим или равным x.
>>> import math
>>> 
>>> math.ceil(3.14)
4
>>> math.ceil(-3.14)
-3

Степени, логарифмирование, экспоненцирование

math.pow(x, y)
Возвращает x в степени y.
>>> import math
>>> 
>>> math.pow(2, 3)
8.0
>>> 
>>> math.pow(3.14, 0.5)
1.772004514666935

В ситуациях pow(x, 0.0) или pow(0.0, x) данная функция всегда возвращает \(1\) даже если x равен NaN, Inf или -Inf. Однако, если x и y являются конечными числами, причем x отрицательное, а y не целое, то будет вызвано исключение ValueError:

>>> math.pow(-2.2, 4.2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: math domain error
math.sqrt(x)
Возвращает квадратный корень числа x.
>>> import math
>>> 
>>> math.sqrt(4)
2.0
>>> 
>>> math.sqrt(3.14)
1.772004514666935
math.log(x[, base])
Если указано только число x, то возвращается натуральный логарифм данного числа. Если указано число x и основание base, то возвращается логарифм числа по указанному основанию.
>>> import math
>>> 
>>> math.log(2.78)
1.0224509277025455
>>> 
>>> math.log(1024, 2)
10.0

По сути, команда log(x, base) равносильна команде log(x)/log(base):

>>> math.log(1024)/math.log(2)
10.0
math.log10(x)
Возвращает десятичный логарифм числа x, вычисление которого происходит немного точнее, чем log(x, 10).
>>> import math
>>> 
>>> math.log10(1000)
3.0
>>> 
>>> #  точное значение десятичного
... #  логарифма от 2 равно
... #  0.301029995663981195213738894724493026768189881462108541310
... math.log10(2)
0.3010299956639812
>>> math.log(2, 10)
0.30102999566398114
math.log2(x)
Возвращает двоичный логарифм числа x, вычисление которого происходит немного точнее, чем log(x, 2).
>>> import math
>>> 
>>> math.log2(2048)
11.0
>>> 
>>> #  точное значение двоичного
... #  логарифма от 10 равно
... #  3.321928094887362347870319429489390175864831393024580612054
... math.log2(10)
3.321928094887362
>>> math.log(10, 2)
3.3219280948873626
math.log1p(x)
Возвращает натуральный логарифм от x увеличенного на \(1\) (x + 1), значение которого расчитывается более точно, особенно для небольших чисел x.
>>> import math
>>> 
>>> x = 0.0001
>>> 
>>> math.log1p(x)
9.999500033330834e-05
>>> 
>>> math.log(x + 1)
9.999500033329732e-05
math.exp(x)
Возвращает e**x.
>>> import math
>>> 
>>> math.exp(1)
2.718281828459045
>>> 
>>> math.exp(3.14)
23.103866858722185
math.expm1(x)
Возвращает e**x - 1, которое вычисляется значительно точнее, чем math.exp(x) - 1, особенно для небольших чисел x.
>>> import math
>>> 
>>> math.expm1(0.0000007)
7.000002450000572e-07
>>> 
>>> math.exp(0.0000007) - 1
7.000002451018617e-07
>>> 
>>> #  точное значение 7.00002450005716676670847339183e-6

Тригонометрические функции

math.sin(x)
Возвращает синус угла x значение которого задано в радианах.
>>> from math import sin, pi
>>> 
>>> sin(0), sin(pi/2), sin(pi/3), sin(pi/4)
(0.0, 1.0, 0.8660254037844386, 0.7071067811865475)
math.cos(x)
Возвращает косинус угла x значение которого задано в радианах.
>>> from math import cos, pi
>>> 
>>> cos(0), cos(pi/2), cos(pi/3), cos(pi/4)
(1.0, 6.123233995736766e-17, 0.5000000000000001, 0.7071067811865476)
math.tan(x)
Возвращает тангенс угла x значение которого задано в радианах.
>>> from math import tan, pi
>>> 
>>> tan(0), tan(pi/3), tan(pi/4)
(0.0, 1.7320508075688767, 0.9999999999999999)

При определенных значениях углов тангенс должен быть равен либо \(-\infty\) либо \(+\infty\), скажем \(\tan (3\pi/2) = +\infty\), a \(\tan (-\pi/2) = -\infty\), но вместо этого мы получаем либо очень большие либо очень маленькие значения типа float:

>>> tan(-pi/2)    # должно быть -Inf, но
-1.633123935319537e+16
>>> 
>>> tan(3*pi/2)    #  должно быть Inf, но
5443746451065123.0
math.asin(x)
Возвращает арксинус значения x, т.е. такое значение угла y (выраженного в радианах) при котором sin(y) = x.
>>> from math import asin, sin, pi
>>> 
>>> pi/6
0.5235987755982988
>>> 
>>> sin(pi/6)
0.49999999999999994
>>> 
>>> asin(0.49999999999999994)
0.5235987755982988
math.acos(x)
Возвращает арккосинус значения x, т.е. возвращает такое значение угла y (выраженного в радианах) при котором cos(y) = x.
>>> from math import acos, cos, pi
>>> 
>>> pi/11
0.28559933214452665
>>> 
>>> cos(pi/11)
0.9594929736144974
>>> 
>>> acos(0.9594929736144974)
0.2855993321445267
math.atan(x)
Возвращает арктангенс значения x, т.е. возвращает такое значение угла y (выраженного в радианах) при котором tan(y) = x.
>>> from math import atan, tan, pi
>>> 
>>> pi/7
0.4487989505128276
>>> 
>>> tan(pi/7)
0.4815746188075286
>>> 
>>> atan(0.4815746188075286)
0.4487989505128276
math.atan2(y, x)
Возвращает арктангенс значения x/y, т.е. возвращает такое значение угла z (выраженного в радианах) при котором tan(z) = x.
>>> from math import atan2, atan, tan, pi
>>> 
>>> atan(0.5)
0.4636476090008061
>>> atan2(1, 2)
0.4636476090008061
>>> 
>>> tan(0.4636476090008061)
0.49999999999999994

Однако, данная функция, в отличие от функции atan(), способна вычислить правильный квадрвнт в котором должно находиться значение результата. Это возможно благодаря тому, что функция принимает два аргумента (x, y) – это координаты точки, которая является концом отрезка начатого в начале координат. Сам по себе, угол между этим отрезком и положительным направлением оси абцисс не несет информации о том где располагается конец этого отрезка, что приводит к одинаковому значению арктангенса, для разных отрезков, но функция atan2() позволяет избежать этого, что бывает очень важно в целом ряде задач:

>>> atan(-0.5)
-0.4636476090008061
>>> 
>>> atan2(-1, 2)
-0.4636476090008061
>>> 
>>> atan2(1, -2)
2.677945044588987
math.hypot(x, y)
Вычисляет значение гипотенузы по заданным значениям катетов x и y. Данная функция равносильна команде sqrt(x*x + y*y).
>>> import math
>>> 
>>> math.hypot(3, 4)
5.0

Преобразование меры углов

math.degrees(x)
Преобразует угол x из радианной меры в градусную.
>>> from math import degrees, pi
>>> 
>>> pi/2    #  угол в радианах
1.5707963267948966
>>> 
>>> degrees(pi/2)    #  тот же угол, но в градусах
90.0
math.radians(x)
Преобразует угол x из градусной меры в радианную.
>>> from math import radians, pi
>>> 
>>> radians(90)
1.5707963267948966
>>> 
>>> pi/2
1.5707963267948966

Гиперболические функции

math.sinh(x)
Возвращает гиперболический синус угла x заданного в радианах.
>>> import math
>>> 
>>> math.sinh(0.4)
0.4107523258028155
math.cosh(x)
Возвращает гиперболический косинус угла x заданного в радианах.
>>> import math
>>> 
>>> math.cosh(0.3)
1.0453385141288605
math.tanh(x)
Возвращает гиперболический тангенс угла x заданного в радианах.
>>> import math
>>> 
>>> math.tanh(0.2)
0.197375320224904
math.asinh(x)
Возвращает гиперболический арксинус значения x, т.е. возвращает такое значение угла y (заданного в радианах) при котором sinh(y) = x.
>>> import math
>>> 
>>> math.asinh(0.4107523258028155)
0.4
math.acosh(x)
Возвращает гиперболический арккосинус значения x, т.е. возвращает такое значение угла y (заданного в радианах) при котором cosh(y) = x.
>>> import math
>>> 
>>> math.acosh(1.0453385141288605)
0.3
math.atanh(x)
Возвращает гиперболический арктангенс значения x, т.е. возвращает такое значение угла y (заданного в радианах) при котором tanh(y) = x.
>>> import math
>>> 
>>> math.atanh(0.197375320224904)
0.2

Константы и специальные значения

math.pi
Возвращает значение математической константы \(\pi\) с точностью, которая зависит от конкретной платформы.
>>> import math
>>> 
>>> math.pi
3.141592653589793
math.e
Возвращает значение математической константы \(e\) с точностью, которая зависит от конкретной платформы.
>>> import math
>>> 
>>> math.e
2.718281828459045
math.inf
Возвращает положительную бесконечность, значение которое является типом float и может присутствовать в математических выражениях.
>>> import math
>>> 
>>> math.inf
inf
>>> 
>>> math.inf**0.5
inf

Данное значение можно получить с помощью команды float('inf'). А что бы получить отрицательную бесконечность достаточно добавить перед командой унарный оператор -:

>>> float('inf')
inf
>>> -math.inf
-inf

Доступно в Python начиная с версии 3.5.

math.nan
Возвращает значение "не число" которое является типом float и может присутствовать в математических выражениях. Равносильно команде float('nan').
>>> import math
>>> 
>>> math.nan
nan
>>> 
>>> float('nan')
nan

Доступно в Python начиная с версии 3.5.

math.isinf(x)
Возвращает True в случаях, когда x является отрицательной или положительной бесконечностью, иначе возвращает False.
>>> import math
>>> 
>>> math.isinf(float('inf'))
True
>>> math.isinf(-math.inf)
True
>>> 
>>> math.isinf(3.14)
False
math.isnan(x)
Возвращает True если x является nan, иначе возвращает False.
>>> import math
>>> 
>>> math.isnan(math.nan)
True
>>> math.isnan(float('nan'))
True
>>> 
>>> math.isnan(3.14)
False
math.isfinite(x)
Возвращает False если x является либо nan, либо inf или -inf, во всех остальных случаях возвращается True.
>>> from math import isfinite
>>> 
>>> isfinite(float('inf'))
False
>>> isfinite(float('nan'))
False
>>> 
>>> isfinite(0)
True

Специальные функции

math.erf(x)
Возвращает значение функции ошибок от указанного значения аргумента x.
>>> import math
>>> 
>>> math.erf(0)
0.0
>>> math.erf(0.476936276)
0.4999999998162208

Доступно в Python начиная с версии 3.2.

math.erfc(x)
Возвращает значение дополнительной функции ошибок от указанного значения аргумента x. Эквивалентна команде 1 - erf(x).
>>> import math
>>> 
>>> math.erfc(2)
0.0046777349810472645
>>> 
>>> 1 - math.erf(2)
0.004677734981047288

Доступно в Python начиная с версии 3.2.

math.gamma(x)
Возвращает значение гамма функции от указанного аргумента x.
>>> import math
>>> 
>>> for x in range(1, 20):
...     print('gamma(', x/2, ') = ', math.gamma(x/2))
... 
gamma( 0.5 ) =  1.7724538509055159
gamma( 1.0 ) =  1.0
gamma( 1.5 ) =  0.8862269254527578
gamma( 2.0 ) =  1.0
gamma( 2.5 ) =  1.329340388179137
gamma( 3.0 ) =  2.0
gamma( 3.5 ) =  3.323350970447842
gamma( 4.0 ) =  6.0
gamma( 4.5 ) =  11.631728396567448
gamma( 5.0 ) =  24.0
gamma( 5.5 ) =  52.342777784553526
gamma( 6.0 ) =  120.0
gamma( 6.5 ) =  287.88527781504433
gamma( 7.0 ) =  720.0
gamma( 7.5 ) =  1871.2543057977882
gamma( 8.0 ) =  5040.0
gamma( 8.5 ) =  14034.407293483413
gamma( 9.0 ) =  40320.0
gamma( 9.5 ) =  119292.46199460902

Данная функция обобщает понятие факториала, на действительные числа (и на комплексные, но в данном случае используются только действительные числа). Если \(x = 0\) то это вызовет исключение ValueError.

Доступно в Python начиная с версии 3.2.

math.lgamma(x)
Возвращает значение натурального логарифма от модуля гамма функции при заданном значении аргумента x.

Данная функция эквивалентна команде math.log(abs(math.gamma(x))).

>>> import math
>>> 
>>> math.lgamma(4)
1.791759469228055
>>> 
>>> math.log(abs(math.gamma(4)))
1.791759469228055

Доступно в Python начиная с версии 3.2.