Pythonのmathモジュールとは、切り上げ・切り捨て・平方根・対数・三角関数など、数値計算でよく使う関数と定数をまとめた標準ライブラリです。 インストールは不要で、import math と1行書くだけで math.ceil(2.1) や math.sqrt(16) のように呼び出せます。

この記事では、mathの関数と定数を用途別の一覧表にまとめ、すべてに1行の実行例と結果を付けました。 さらに、ceil・floor・trunc・round・intを正の値と負の値で比べた表、sqrt・isqrt・cbrtの違い、math domain error の再現と直し方、isclose での比較、sumprod や fma が使えるバージョンまで扱います。実行結果はすべて Python 3.14.7 と Python 3.11.15 で実際に動かして確かめたものです。

mathモジュールの早見表

やりたいことから関数を探せる表です。 まずはこの表だけで用が足ります。

やりたいこと 書き方 結果 補足
切り上げ math.ceil(2.1) 3 戻り値は int
切り捨て(小さい方へ) math.floor(2.9) 2 負の値では -2.9 → -3
小数部を取り除く(0の方へ) math.trunc(-2.9) -2 int(-2.9) と同じ結果
平方根 math.sqrt(16) 4.0 戻り値は float
整数の平方根 math.isqrt(17) 4 戻り値は int(3.8以降)
立方根 math.cbrt(-8) -2.0 負の値も可(3.11以降)
累乗 math.pow(2, 10) 1024.0 整数のままなら 2 ** 10
円周率 math.pi 3.141592653589793 定数
自然対数・常用対数 math.log(math.e) / math.log10(1000) 1.0 / 3.0 2が底なら math.log2
度とラジアンの変換 math.radians(180) / math.degrees(math.pi) 3.141592653589793 / 180.0 三角関数はラジアンで渡す
最大公約数・最小公倍数 math.gcd(12, 18) / math.lcm(4, 6) 6 / 12 lcm は 3.9以降
階乗・組み合わせ math.factorial(5) / math.comb(5, 2) 120 / 10 comb は 3.8以降
小数どうしの比較 math.isclose(0.1 + 0.2, 0.3) True == では False
NaN の判定 math.isnan(math.nan) True nan == nan は False

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Python mathモジュールの使い方|切り上げ・切り捨て・平方根と関数一覧」

mathモジュールの基本と読み込み方

import の書き方3通り

基本は import math です。 関数名の前に math. が付くので、どのモジュールの関数かがひと目でわかります。

import math
print(math.sqrt(16))        # 4.0

from math import sqrt, pi   # 使う名前だけ取り込む
print(sqrt(16), pi)         # 4.0 3.141592653589793

import math as m            # 別名を付ける
print(m.floor(2.9))         # 2
書き方 呼び出し方 向いている場面
import math math.sqrt(x) ふだんの基本形。出どころが明確
from math import sqrt sqrt(x) 同じ関数を何度も書く数式
import math as m m.sqrt(x) 数式が長くなるとき
from math import * sqrt(x) 対話モードでの試し書き向き。pow など組み込み関数と同じ名前が上書きされるため、ファイルに残すコードでは上の3つを使うと読みやすくなります

関数と定数はいくつあるか

dir(math) で数えると、Python 3.14.7 では62個(関数57+定数5)、Python 3.11.15 では60個でした。差の2個は、3.12で追加された sumprod と、3.13で追加された fma です。

import math
names = [n for n in dir(math) if not n.startswith("_")]
print(len(names))   # 3.14.7 では 62、3.11.15 では 60

mathが扱うのは実数(int と float)です。複素数は cmath、配列全体への一括計算は NumPy、10進数での厳密な計算は decimal という役割分担になっています。

切り上げ・切り捨て:ceil・floor・trunc・round・intの違い

正負の値で比べた表

切り上げは math.ceil、切り捨ては math.floor、小数部を取り除くのは math.trunc です。 正の値では floor と trunc が同じ結果になりますが、負の値で差が出ます。次の表は Python 3.14.7 で実行した結果です(3.11.15 でも同じでした)。

値 x math.ceil(x) math.floor(x) math.trunc(x) int(x) round(x)
2.4 3 2 2 2 2
2.5 3 2 2 2 2
2.6 3 2 2 2 3
3.5 4 3 3 3 4
0.5 1 0 0 0 0
-0.5 0 -1 0 0 0
-2.4 -2 -3 -2 -2 -2
-2.5 -2 -3 -2 -2 -2
-2.6 -2 -3 -2 -2 -3
-3.5 -3 -4 -3 -3 -4

表から読み取れるポイントは次の4つです。

  • ceil は「数直線で右(大きい方)」へ進みます。 -2.4 の切り上げは -2 です。
  • floor は「数直線で左(小さい方)」へ進みます。 -2.4 の切り捨ては -3 になります。
  • trunc と int は「0に近い方」へ進みます。 正の値では floor と同じ、負の値では ceil と同じ結果です。
  • round は「ちょうど真ん中(.5)のとき偶数側」へ丸めます。 round(2.5) は 2、round(3.5) は 4 です。学校で習う四捨五入とは結果が変わる値があります。

どれを選ぶかの判断表

やりたいこと 選ぶもの 例と結果
必要な箱の数・ページ数(余りが出たら1つ増やす) math.ceil math.ceil(95 / 10) → 10
負の値でも常に小さい方へそろえる math.floor math.floor(-2.4) → -3
符号に関係なく小数部を取り除く math.trunc または int math.trunc(-2.9) → -2
近い整数にする(.5は偶数側) round round(2.5) → 2
学校で習う四捨五入(.5は必ず繰り上げ) decimal の ROUND_HALF_UP 下のコードを参照

math.trunc(x) と int(x) は数値に対しては同じ結果です。違いは文字列で、int("3") は 3 を返しますが、math.trunc("3") は TypeError: type str doesn't define __trunc__ method になります。「数値の小数部を取り除く」という意図をコードで伝えたいときは trunc、文字列からの変換も兼ねるときは int と使い分けると読みやすくなります。

小数第n位・10や100の単位で切り上げ/切り捨てる

ceil と floor は整数に丸める関数なので、桁を指定したいときは「掛けて、丸めて、割る」の形にします。

import math

x = 3.14159
print(math.ceil(x * 100) / 100)          # 3.15  小数第3位を切り上げ
print(math.floor(x * 100) / 100)         # 3.14  小数第3位を切り捨て
print(math.floor(-3.14159 * 100) / 100)  # -3.15 floor は小さい方へ
print(math.trunc(-3.14159 * 100) / 100)  # -3.14 trunc は0の方へ

print(math.ceil(1234 / 100) * 100)       # 1300  100単位で切り上げ
print(math.floor(1234 / 100) * 100)      # 1200  100単位で切り捨て

整数どうしなら、mathを使わずに //(切り捨て除算)でも書けます。1234 // 100 は 12、-(-1234 // 100) は 13 です。-(-a // b) は「符号を反転して切り捨て、もう一度反転する」ことで切り上げになる定番の書き方です。

つまずく箇所:小数の掛け算のあとに ceil を使うと1つ多くなることがある

float の計算結果にはごく小さな誤差が乗るため、ceil の結果が1つ大きくなる値があります。

import math
print(0.1 * 3)                               # 0.30000000000000004
print(math.ceil(0.1 * 3 * 10))               # 4  (3 を期待していた)
print(math.ceil(round(0.1 * 3 * 10, 9)))     # 3  先に誤差を落としてから切り上げ

0.1 * 3 が内部では 0.30000000000000004 になるため、10倍すると3をわずかに超え、ceil が4を返します。対処は2つあります。

対処 書き方 向いている場面
先に round で誤差を落とす math.ceil(round(v, 9)) 手軽に直したいとき
10進数で計算する decimal.Decimal("0.1") * 3 小数の桁を厳密に扱いたいとき

.5 を必ず繰り上げる四捨五入は decimal で書けます。

from decimal import Decimal, ROUND_HALF_UP

print(Decimal("2.5").quantize(Decimal("1"), rounding=ROUND_HALF_UP))       # 3
print(Decimal("2.675").quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))  # 2.68
print(round(2.675, 2))                                                     # 2.67

round(2.675, 2) が 2.67 になるのは、float の 2.675 が内部では 2.67499999999999982236431605997495353221893310546875 として保持されているためです(Decimal(2.675) で確認できます)。

丸め・小数部の関数一覧

関数 実行例 結果 説明
math.ceil(x) math.ceil(2.1) 3 x 以上で最小の整数
math.floor(x) math.floor(2.9) 2 x 以下で最大の整数
math.trunc(x) math.trunc(-2.9) -2 小数部を取り除く
math.fabs(x) math.fabs(-3) 3.0 絶対値を float で返す(abs(-3) は 3)
math.modf(x) math.modf(3.75) (0.75, 3.0) 小数部と整数部に分ける
math.fmod(x, y) math.fmod(-7, 3) -1.0 余り。符号は x に合わせる(-7 % 3 は 2)
math.remainder(x, y) math.remainder(7, 4) -1.0 最も近い倍数との差(3.7以降)
math.copysign(x, y) math.copysign(3, -0.0) -3.0 x の大きさに y の符号を付ける

math.ceil(2.1) の戻り値の型は int です。math.ceil(math.inf) は OverflowError: cannot convert float infinity to integer、math.ceil(math.nan) は ValueError: cannot convert float NaN to integer になるので、外から来た値を丸める前には後述の math.isfinite で確かめると安心です。

平方根と累乗:sqrt・isqrt・cbrtの違い

3つの関数の比較表

平方根は math.sqrt、整数のまま平方根を求めるなら math.isqrt、立方根は math.cbrt です。

関数 実行例 結果 戻り値の型 負の値を渡すと 追加バージョン
math.sqrt(x) math.sqrt(16) 4.0 float ValueError 当初から
math.sqrt(x) math.sqrt(2) 1.4142135623730951 float ― ―
math.isqrt(n) math.isqrt(17) 4 int ValueError 3.8
math.cbrt(x) math.cbrt(-8) -2.0 float 計算できる 3.11
math.cbrt(x) math.cbrt(27) 3.0000000000000004 float ― ―
x ** 0.5 16 ** 0.5 4.0 float 複素数になる 演算子

math.isqrt(n) は「2乗して n を超えない最大の整数」を返します。math.isqrt(17) が 4 なのは、4×4=16 ≤ 17 < 25=5×5 だからです。float を渡すと TypeError: 'float' object cannot be interpreted as an integer になります。

大きな整数では isqrt が正確

float は約15〜17桁までしか正確に表せないため、大きな整数の平方根は int(math.sqrt(n)) だとずれることがあります。

import math

n = 99999999999999999 ** 2          # 17桁の数の2乗
print(int(math.sqrt(n)))            # 100000000000000000  (1だけずれる)
print(math.isqrt(n))                # 99999999999999999   (正確)

print(math.isqrt(10 ** 400) == 10 ** 200)   # True
print(math.sqrt(10 ** 400))
100000000000000000
99999999999999999
True
OverflowError: int too large to convert to float

math.sqrt は引数をいったん float に変換するので、float の範囲を超える整数は OverflowError になります。math.isqrt は整数のまま計算するため、桁数に上限がありません。素数判定や「平方数かどうか」の判定には isqrt が向いています。

import math

def is_prime(n: int) -> bool:
    if n < 2:
        return False
    return all(n % i for i in range(2, math.isqrt(n) + 1))

print([n for n in range(30) if is_prime(n)])
# [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

立方根は cbrt、ただし結果は isclose で比べる

math.cbrt(27) の結果は 3.0000000000000004 で、math.cbrt(27) == 3 は False でした(3.14.7・3.11.15とも)。立方根の結果を整数と比べるときは math.isclose(math.cbrt(27), 3)(結果は True)か、round(math.cbrt(27)) を使います。

負の値の立方根は、書き方によって結果が大きく変わります。

書き方 結果
math.cbrt(-8) -2.0
(-8) ** (1/3) (1.0000000000000002+1.7320508075688772j)(複素数)
math.pow(-8, 1/3) ValueError: math domain error

実数の答え -2.0 がほしいときは math.cbrt を選びます。

平方根・累乗・指数の関数一覧

関数 実行例 結果 説明
math.sqrt(x) math.sqrt(16) 4.0 平方根
math.isqrt(n) math.isqrt(17) 4 整数の平方根(3.8以降)
math.cbrt(x) math.cbrt(-8) -2.0 立方根(3.11以降)
math.pow(x, y) math.pow(2, 10) 1024.0 累乗。常に float
math.exp(x) math.exp(1) 2.718281828459045 e の x 乗
math.exp2(x) math.exp2(10) 1024.0 2 の x 乗(3.11以降)
math.expm1(x) math.expm1(1e-10) 1.00000000005e-10 e の x 乗 − 1 を、x が小さくても精度よく
math.hypot(*座標) math.hypot(3, 4) 5.0 原点からの距離。math.hypot(1, 2, 2) は 3.0
math.dist(p, q) math.dist((0, 0), (3, 4)) 5.0 2点間の距離(3.8以降)

math.pow(2, 10) は 1024.0(float)、2 ** 10 は 1024(int)です。整数のまま結果がほしいときは ** 演算子、float でそろえたいときは math.pow と覚えると迷いません。

対数と指数:log・log2・log10

math.log(x) は自然対数(底が e)、math.log(x, 底) で底を指定できます。 底が2や10のときは専用の関数のほうが正確です。

関数 実行例 結果 説明
math.log(x) math.log(math.e) 1.0 自然対数
math.log(x, base) math.log(8, 2) 3.0 底を指定
math.log2(x) math.log2(1024) 10.0 底が2(3.3以降)
math.log10(x) math.log10(1000) 3.0 底が10
math.log1p(x) math.log1p(1e-10) 9.999999999500001e-11 log(1+x) を、x が小さくても精度よく

底を指定する形は内部で割り算をするため、わずかな誤差が出る値があります。

import math
print(math.log(1000, 10))   # 2.9999999999999996
print(math.log10(1000))     # 3.0
print(math.log(125, 5))     # 3.0000000000000004

底が10なら math.log10、底が2なら math.log2 を使うと、きりのよい値がそのまま返ります。 それ以外の底では、結果を math.isclose で比べるか round で整えます。整数の桁数は math.floor(math.log10(12345)) + 1(結果は 5)でも求められますが、len(str(12345)) のほうが誤差の心配がなく簡単です。

三角関数と角度の変換

mathの三角関数は、角度を「度」ではなく「ラジアン」で受け取ります。 度で考えているときは math.radians で変換してから渡します。

import math
print(math.sin(30))                  # -0.9880316240928618  30ラジアンとして計算される
print(math.sin(math.radians(30)))    # 0.49999999999999994  30度
print(round(math.sin(math.radians(30)), 10))   # 0.5
関数 実行例 結果 説明
math.radians(度) math.radians(180) 3.141592653589793 度 → ラジアン
math.degrees(rad) math.degrees(math.pi) 180.0 ラジアン → 度
math.sin(x) math.sin(math.pi / 2) 1.0 正弦
math.cos(x) math.cos(math.pi) -1.0 余弦
math.tan(x) math.tan(math.pi / 4) 0.9999999999999999 正接
math.asin(x) math.asin(1) 1.5707963267948966 逆正弦(引数は -1〜1)
math.acos(x) math.acos(1) 0.0 逆余弦(引数は -1〜1)
math.atan(x) math.atan(1) 0.7853981633974483 逆正接
math.atan2(y, x) math.atan2(1, -1) 2.356194490192345 座標から角度。象限を正しく判定
math.sinh(x) math.sinh(1) 1.1752011936438014 双曲線正弦
math.cosh(x) math.cosh(0) 1.0 双曲線余弦
math.tanh(x) math.tanh(1) 0.7615941559557649 双曲線正接

このほか逆双曲線関数の asinh・acosh・atanh があります。

math.sin(math.pi) は 0 ではなく 1.2246467991473532e-16 を返します。 math.pi が円周率の近似値(float)だからです。0かどうかは math.isclose(math.sin(math.pi), 0, abs_tol=1e-9)(結果は True)で判定します。

2点を結ぶ線の角度は atan2 で求めます。引数の順番が (y, x) である点に注意してください。

import math
p, q = (1, 2), (4, 6)
print(math.dist(p, q))                                              # 5.0
print(math.degrees(math.atan2(q[1] - p[1], q[0] - p[0])))           # 53.13010235415598

整数演算:階乗・最大公約数・組み合わせ

整数を受け取り整数を返す関数は、桁数がどれだけ大きくても正確に計算できます。

関数 実行例 結果 説明
math.factorial(n) math.factorial(5) 120 階乗
math.gcd(*整数) math.gcd(12, 18, 30) 6 最大公約数。3個以上は 3.9以降
math.lcm(*整数) math.lcm(4, 6) 12 最小公倍数(3.9以降)
math.comb(n, k) math.comb(5, 2) 10 組み合わせ nCk(3.8以降)
math.perm(n, k) math.perm(5, 2) 20 順列 nPk(3.8以降)
math.isqrt(n) math.isqrt(17) 4 整数の平方根(3.8以降)
math.prod(iterable) math.prod([1, 2, 3, 4]) 24 すべての積(3.8以降)。空なら 1

math.factorial(2.0) のように float を渡すと TypeError: 'float' object cannot be interpreted as an integer になります。math.factorial(-1) は ValueError: factorial() not defined for negative values です。「10人から3人を選ぶ」通り数は math.comb(10, 3) で 120 と求められます。

合計と積:fsum・prod・sumprod・fma

関数 実行例 結果 追加バージョン
math.fsum(iterable) math.fsum([0.1] * 10) 1.0 当初から
math.prod(iterable) math.prod([1, 2, 3, 4]) 24 3.8
math.sumprod(p, q) math.sumprod([1, 2, 3], [4, 5, 6]) 32 3.12
math.fma(x, y, z) math.fma(2, 3, 4) 10.0 3.13

fsum:小数の合計を誤差なく求める

math.fsum は途中の誤差を追跡しながら合計するので、float の合計が正確になります。組み込みの sum との差は、Pythonのバージョンによって変わりました。

式 Python 3.11.15 Python 3.14.7
sum([0.1] * 10) 0.9999999999999999 1.0
math.fsum([0.1] * 10) 1.0 1.0
sum([0.1, 0.2, 0.3]) 0.6000000000000001 0.6
sum([1e16, 1.0, -1e16]) 0.0 1.0
math.fsum([1e16, 1.0, -1e16]) 1.0 1.0

手元の実行では、3.14.7 の sum は float の合計で fsum と同じ結果を返しました。どのバージョンでも同じ結果にしたいときは math.fsum を選ぶと確実です。

sumprod(3.12以降):2つのリストの積の合計

math.sumprod(p, q) は、対応する要素どうしを掛けて合計します。単価と数量から合計を出す、ベクトルの内積を求める、といった場面で1行になります。

import math
prices = [120, 80, 300]
counts = [2, 5, 1]
print(math.sumprod(prices, counts))                  # 940
print(sum(p * c for p, c in zip(prices, counts)))    # 940  3.11以前はこちら

Python 3.11.15 で math.sumprod を呼ぶと AttributeError: module 'math' has no attribute 'sumprod' になりました。3.11以前でも動かすコードでは sum(... for ... in zip(...)) の形を使います。

fma(3.13以降):掛けて足す計算を1回の丸めで行う

math.fma(x, y, z) は x * y + z を、途中で丸めずに計算します。ふつうの式は「掛け算で1回、足し算で1回」丸めが入りますが、fma は最後の1回だけです。

import math
print(math.fma(2, 3, 4))        # 10.0
print(0.1 * 10 - 1)             # 0.0
print(math.fma(0.1, 10, -1))    # 5.551115123125783e-17

0.1 は内部では0.1よりわずかに大きい値です。ふつうの式では 0.1 * 10 が丸められて 1.0 になり差が消えますが、fma はその差 5.55e-17 を取り出せます。数値計算の精度を詰めたいときに使う関数で、ふだんの計算では x * y + z のままで十分です。

判定と比較:isclose・isnan・isinf・isfinite

小数どうしは == ではなく isclose で比べる

float の計算結果を == で比べると、見た目が同じでも False になることがあります。math.isclose を使うと「十分に近いか」で判定できます。

import math
print(0.1 + 0.2)                        # 0.30000000000000004
print(0.1 + 0.2 == 0.3)                 # False
print(math.isclose(0.1 + 0.2, 0.3))     # True

math.isclose(a, b, rel_tol=1e-09, abs_tol=0.0) には許容範囲の指定が2つあります。

引数 意味 既定値 使いどころ
rel_tol 相対的な許容差(大きいほうの値に対する割合) 1e-09 ふつうの値どうしの比較
abs_tol 絶対的な許容差 0.0 0との比較で指定する

0と比べるときは abs_tol の指定が必要です。 相対的な許容差は「値の大きさ×割合」なので、相手が0だと許容範囲も0になるためです。

import math
print(math.isclose(1e-10, 0))                    # False
print(math.isclose(1e-10, 0, abs_tol=1e-9))      # True
print(math.isclose(1000.0, 1000.1, rel_tol=1e-3))  # True  0.1%以内なら同じとみなす

NaN と無限大の判定

関数・定数 実行例 結果 説明
math.isclose(a, b) math.isclose(0.1 + 0.2, 0.3) True 近いかどうか(3.5以降)
math.isnan(x) math.isnan(math.nan) True NaN(数でない値)か
math.isinf(x) math.isinf(-math.inf) True 正または負の無限大か
math.isfinite(x) math.isfinite(math.inf) False 有限の数か(NaN と無限大以外)
math.nextafter(x, y) math.nextafter(1.0, 2.0) 1.0000000000000002 y 方向の次の float(3.9以降)
math.ulp(x) math.ulp(1.0) 2.220446049250313e-16 x の最下位ビットの大きさ(3.9以降)
math.frexp(x) math.frexp(8.0) (0.5, 4) 仮数と指数に分ける(0.5 × 2の4乗)
math.ldexp(x, i) math.ldexp(0.5, 4) 8.0 frexp の逆

NaN は自分自身と比べても等しくなりません。 math.nan == math.nan は False なので、NaN かどうかは必ず math.isnan で判定します。CSVなどから読み込んだ値を計算に使う前に math.isfinite(x) を通すと、NaN と無限大をまとめて見分けられます。

定数と特殊関数

名前 値・実行例 説明
math.pi 3.141592653589793 円周率 π
math.e 2.718281828459045 自然対数の底
math.tau 6.283185307179586 2π(3.6以降)。円周は math.tau * r
math.inf inf 正の無限大(3.5以降)。math.inf > 10 ** 400 は True
math.nan nan 数でない値(3.5以降)
math.erf(x) math.erf(1) → 0.8427007929497149 誤差関数。erfc は 1 − erf
math.gamma(x) math.gamma(5) → 24.0 ガンマ関数(4の階乗と同じ値)
math.lgamma(x) math.lgamma(5) → 3.178053830347945 ガンマ関数の絶対値の自然対数

math.inf は「最小値を探すときの初期値」として便利です。best = math.inf としておけば、どんな数と比べても最初の1回で置き換わります。

import math
r = 3
print(round(math.pi * r ** 2, 2))   # 28.27  円の面積
print(round(math.tau * r, 2))       # 18.85  円周

math domain errorの原因と直し方

エラーを再現する

ValueError: math domain error は、関数が計算できる範囲(定義域)の外の値を渡したときに出るエラーです。 負の値の平方根、0や負の値の対数、-1〜1の外の値の逆三角関数が代表例です。

Python 3.11.15 では次のように表示されました。

>>> math.sqrt(-1)
ValueError: math domain error
>>> math.log(0)
ValueError: math domain error
>>> math.acos(2)
ValueError: math domain error

Python 3.14.7 では、同じ操作でも原因がわかるメッセージに変わっていました。 検索したエラー文と手元の表示が違うときは、Pythonのバージョンを確かめてみてください。

式 Python 3.11.15 Python 3.14.7
math.sqrt(-1) ValueError: math domain error ValueError: expected a nonnegative input, got -1.0
math.log(0) ValueError: math domain error ValueError: expected a positive input
math.log(-1) ValueError: math domain error ValueError: expected a positive input
math.acos(2) ValueError: math domain error ValueError: expected a number in range from -1 up to 1, got 2.0
math.gamma(0) ValueError: math domain error ValueError: expected a noninteger or positive integer, got 0.0
math.pow(-8, 1/3) ValueError: math domain error ValueError: math domain error
math.pow(0, -1) ValueError: math domain error ValueError: math domain error
math.exp(1000) OverflowError: math range error OverflowError: math range error

math range error は別のエラーで、結果が float で表せる範囲を超えたときに出ます。

原因別の直し方

原因 直す前 直した後
負の値の平方根 math.sqrt(x) 先に if x < 0: で分ける。複素数でよければ cmath.sqrt(x)
0や負の値の対数 math.log(x) if x > 0: で分ける。0に近い値を足すなら math.log1p(x)
誤差で 1 をわずかに超えた値の acos / asin math.acos(c) math.acos(max(-1.0, min(1.0, c)))
負の値の立方根 math.pow(x, 1/3) math.cbrt(x)
0 の負の累乗 math.pow(0, -1) 0 かどうかを先に判定する

見つけにくい例:計算誤差で1をわずかに超える

理論上は -1〜1 に収まる値でも、float の誤差で 1.0000000000000002 になり、acos がエラーになることがあります。 同じベクトルどうしの角度を求める例で再現します。

import math

a = (1, 1, 1)
dot = sum(x * x for x in a)                       # 同じベクトル同士の内積
cos = dot / (math.hypot(*a) * math.hypot(*a))     # 理論上は 1.0
print(repr(cos))
try:
    print(math.acos(cos))
except ValueError as e:
    print("ValueError:", e)

cos = max(-1.0, min(1.0, cos))                    # -1〜1 に収める
print(math.acos(cos))
1.0000000000000002
ValueError: expected a number in range from -1 up to 1, got 1.0000000000000002
0.0

(Python 3.14.7 の結果。3.11.15 では2行目が ValueError: math domain error でした。)max(-1.0, min(1.0, 値)) で範囲に収めてから渡すのが定番の対処です。

入力値を事前に確かめる書き方と、例外を受け取る書き方のどちらでも対応できます。

import math
import cmath

def safe_sqrt(x):
    if x < 0:
        return None
    return math.sqrt(x)

print(safe_sqrt(9), safe_sqrt(-9))   # 3.0 None
print(cmath.sqrt(-1))                # 1j

コピペで使える用途別コード

よくある8つの計算を1つのファイルにまとめました。 そのまま保存して python3 sample.py で動きます(Python 3.8以降)。

import math

# 1) ページ数:95件を10件ずつ表示
print(math.ceil(95 / 10))            # 10

# 2) 2点間の距離と角度
p, q = (1, 2), (4, 6)
print(math.dist(p, q))               # 5.0
print(math.degrees(math.atan2(q[1] - p[1], q[0] - p[0])))

# 3) 円の面積と円周(半径3)
r = 3
print(round(math.pi * r ** 2, 2), round(math.tau * r, 2))

# 4) 素数判定(isqrt で調べる範囲を絞る)
def is_prime(n: int) -> bool:
    if n < 2:
        return False
    return all(n % i for i in range(2, math.isqrt(n) + 1))
print([n for n in range(30) if is_prime(n)])

# 5) 整数の桁数
print(len(str(12345)), math.floor(math.log10(12345)) + 1)

# 6) 組み合わせ:10人から3人を選ぶ
print(math.comb(10, 3))

# 7) 小数第2位までで切り上げ・切り捨て
x = 3.14159
print(math.ceil(x * 100) / 100, math.floor(x * 100) / 100)

# 8) 100単位で切り上げ・切り捨て
print(math.ceil(1234 / 100) * 100, math.floor(1234 / 100) * 100)
10
5.0
53.13010235415598
28.27 18.85
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
5 5
120
3.15 3.14
1300 1200

Python 3.14.7 と 3.11.15 で同じ出力になることを確かめました。

バージョン別:追加された関数の一覧

新しめの関数は、動かすPythonのバージョンによっては使えません。 追加バージョンは公式ドキュメント(Python 3.14.8 の math ページ)で確認し、3.11.15 と 3.14.7 で動作を確かめました。

バージョン 追加された関数・定数
3.5 isclose、gcd、inf、nan
3.6 tau
3.7 remainder
3.8 isqrt、comb、perm、prod、dist(hypot が3個以上の引数に対応)
3.9 lcm、nextafter、ulp(gcd が任意個数の引数に対応)
3.11 cbrt、exp2
3.12 sumprod(nextafter に steps 引数)
3.13 fma

バージョンは python3 --version、関数があるかどうかは hasattr(math, "sumprod") で確かめられます。

mathと他の手段の使い分け

計算の対象 選ぶもの 理由
1つの数値(int・float) math 標準ライブラリで追加の準備が不要
リストや配列の全要素 NumPy(np.sqrt(arr) など) 配列をまとめて計算できる
複素数 cmath cmath.sqrt(-1) が 1j を返す
小数の桁を厳密に扱う decimal 10進数のまま計算し、丸め方を指定できる
分数のまま扱う fractions Fraction(1, 3) のように誤差なく保持
平均・中央値などの統計 statistics mean、median などがそろう

mathの関数にリストをそのまま渡すと TypeError: must be real number, not list になります。リストの各要素に適用するときは [math.sqrt(v) for v in values] のように内包表記を使います。

よくある質問

Q. math.floor と int はどう違いますか? A. 正の値では同じ結果ですが、負の値で変わります。math.floor(-2.5) は -3(小さい方へ)、int(-2.5) は -2(0の方へ)です。int と同じ動きをするのは math.trunc です。

Q. round(2.5) が 3 ではなく 2 になるのはなぜですか? A. Pythonの round は、ちょうど真ん中の値を偶数側へ丸める方式だからです。round(3.5) は 4 になります。.5 を必ず繰り上げたいときは、decimal の ROUND_HALF_UP を使います。

Q. math.sqrt と ** 0.5 はどちらを使えばよいですか? A. 実数の平方根なら math.sqrt が読みやすく、負の値を渡したときにエラーで気づけます。(-4) ** 0.5 は複素数を返すため、意図しない値がそのまま後続の計算へ流れることがあります。大きな整数なら math.isqrt が正確です。

Q. math.sumprod や math.fma が見つからないと表示されます。 A. AttributeError: module 'math' has no attribute 'sumprod' は、Pythonが 3.11 以前のときに出ます。sumprod は 3.12、fma は 3.13 で追加されました。sum(x * y for x, y in zip(p, q)) で同じ計算ができます。

まとめ

  • 切り上げは math.ceil、切り捨ては math.floor、小数部の除去は math.trunc。 負の値では floor が小さい方へ、trunc と int が0の方へ進む。
  • round は .5 を偶数側へ丸める。 必ず繰り上げたいときは decimal の ROUND_HALF_UP。
  • 平方根は math.sqrt(float)、大きな整数は math.isqrt(int)、立方根は math.cbrt。 負の値の立方根も cbrt なら実数で返る。
  • 小数の比較は math.isclose。 0と比べるときは abs_tol を指定する。NaN の判定は math.isnan。
  • math domain error は定義域の外の値が原因。 事前の条件分岐か、max(-1.0, min(1.0, x)) で範囲に収めて直す。3.14 では原因がわかるメッセージに変わっている。
  • sumprod は 3.12、fma は 3.13、cbrt と exp2 は 3.11 で追加。 動かす環境のバージョンを確かめてから使う。
  • 三角関数はラジアンで渡す。 度で考えるときは math.radians で変換する。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Python mathモジュールの使い方|切り上げ・切り捨て・平方根と関数一覧」

株式会社RJCでは、Pythonのmathモジュールや数値計算の基礎を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?