# `math` --- 數學函式

此模組提供對常見數學函式與常數的存取，包括於 C 標準中定義的那些。

這些函式不支援複數；若你需要計算複數，請使用 `cmath` 模組的同名函式。這是因為大多數的使用者並不想學習那麼多理解複數所需的數學概念，所以根據支援複數與否分為兩種函式。收到一個例外而非複數回傳值，有助於程式設計師提早察覺參數中包含非預期的複數，進而從源頭查出導致此情況的原因。

此模組提供下列函式。除非特意註明，否則回傳值皆為浮點數。

數論函式
`comb(n, k)` | 從 n 個物品中不重複且不考慮排序地取出 k 個物品的方法數。
`factorial(n)` | n 的階乘
`gcd(*integers)` | 整數引數的最大公因數
`isqrt(n)` | 非負整數 n 的整數平方根
`lcm(*integers)` | 整數引數的最小公倍數
`perm(n, k)` | 從 n 個物品中不重複但考慮排序地取出 k 個物品的方法數。
浮點數算術運算
`ceil(x)` | x 的上取整值，即大於或等於 x 的最小整數
`fabs(x)` | x 的絕對值。
`floor(x)` | x 的下取整值，即小於或等於 x 的最大整數
`fma(x, y, z)` | 融合乘加運算：`(x * y) + z`
`fmod(x, y)` | 除法 `x / y` 的餘數
`modf(x)` | x 的小數部分與整數部分
`remainder(x, y)` | x 相對於 y 的餘數
`trunc(x)` | x 的整數部分
浮點數操作函式
`copysign(x, y)` | 帶有 y 的正負號的 x 的量值（絕對值）
`frexp(x)` | x 的尾數與指數
`isclose(a, b, rel_tol, abs_tol)` | 檢查 a 與 b 兩值是否足夠接近
`isfinite(x)` | 檢查 x 是否既非無限值也非 NaN
`isinf(x)` | 檢查 x 是否為正無限或負無限
`isnan(x)` | 檢查 x 是否為 NaN（非數值）
`ldexp(x, i)` | `x * (2**i)`，`frexp()` 的反函式
`nextafter(x, y, steps)` | 從 x 向 y 移動 steps 步的浮點數值
`ulp(x)` | x 的最低有效位元的值
次方、指數與對數函式
`cbrt(x)` | x 的立方根
`exp(x)` | e 的 x 次方
`exp2(x)` | 2 的 x 次方
`expm1(x)` | e 的 x 次方減 1
`log(x, base)` | x 以給定底數（預設為 e）的對數
`log1p(x)` | 1+x 的自然對數（以 e 為底）
`log2(x)` | x 的以 2 為底的對數
`log10(x)` | x 的以 10 為底的對數
`pow(x, y)` | x 的 y 次方
`sqrt(x)` | x 的平方根
總和與乘積函式
`dist(p, q)` | 兩點 p 與 q 之間的歐幾里得距離，各點以座標的可疊代物件表示
`fsum(iterable)` | 輸入 iterable 中所有值的總和
`hypot(*coordinates)` | 座標可疊代物件的歐幾里得範數
`prod(iterable, start)` | 輸入 iterable 中所有元素與 start 起始值的乘積
`sumprod(p, q)` | 兩個可疊代物件 p 與 q 各元素乘積的總和
角度轉換
`degrees(x)` | 將角度 x 從弧度轉換為度
`radians(x)` | 將角度 x 從度轉換為弧度
三角函式
`acos(x)` | x 的反餘弦
`asin(x)` | x 的反正弦
`atan(x)` | x 的反正切
`atan2(y, x)` | `atan(y / x)`
`cos(x)` | x 的餘弦
`sin(x)` | x 的正弦
`tan(x)` | x 的正切
雙曲函式
`acosh(x)` | x 的反雙曲餘弦
`asinh(x)` | x 的反雙曲正弦
`atanh(x)` | x 的反雙曲正切
`cosh(x)` | x 的雙曲餘弦
`sinh(x)` | x 的雙曲正弦
`tanh(x)` | x 的雙曲正切
特殊函式
`erf(x)` | 在 x 處的誤差函式值
`erfc(x)` | 在 x 處的互補誤差函式值
`gamma(x)` | 在 x 處的 Gamma 函式值
`lgamma(x)` | 在 x 處的 Gamma 函式絕對值的自然對數
常數
`pi` | π = 3.141592...
`e` | e = 2.718281...
`tau` | τ = 2π = 6.283185...
`inf` | 正無限大
`nan` | 「非數值」（NaN）

## 數論函式

math.comb(n, k)

  回傳從 n 個物品中不重複且不考慮排序地取出 k 個物品的方法數。

  當 `k <= n` 時其值為 `n! / (k! * (n - k)!)`，否則其值為 `0`。

  因為此值等同於 `(1 + x)ⁿ` 進行多項式展開後第 k 項的係數，所以又稱為二項式係數。

  當任一參數非整數型別時會引發 `TypeError`。當任一參數為負數時會引發 `ValueError`。

  在 3.8 版被加入.

math.factorial(n)

  回傳非負整數 n 的階乘。

  在 3.10 版的變更: 現在已經不允許傳入其值為整數的浮點數（如：`5.0`）。

math.gcd(*integers)

  回傳指定整數引數的最大公因數。若存在任一非零引數，回傳值為所有引數共有因數中最大的正整數。若所有引數皆為零，則回傳值為 `0`。`gcd()` 若未傳入任何引數也將回傳 `0`。

  在 3.5 版被加入.

  在 3.9 版的變更: 新增支援任意數量的引數。先前僅支援兩個引數。

math.isqrt(n)

  回傳非負整數 n 的整數平方根。此值為 n 精確平方根經下取整的值，亦等同於滿足 a² ≤ n 的最大整數值 a。

  於有些應用程式中，取得滿足 n ≤ a² 的最小整數值 a ── 或者說 n 精確平方根經上取整的值 ── 會更加方便。對正數 n，此值可使用 `a = 1 + isqrt(n - 1)` 計算。

  在 3.8 版被加入.

math.lcm(*integers)

  回傳指定整數引數的最小公倍數。若所有引數值皆非零，回傳值為所有引數共有倍數中最小的正整數。若存在任一引數值為零，則回傳值為 `0`。`lcm()` 若未傳入任何引數將回傳 `1`。

  在 3.9 版被加入.

math.perm(n, k=None)

  回傳從 n 個物品中不重複且考慮排序地取出 k 個物品的方法數。

  當 `k <= n` 時其值為 `n! / (n - k)!`，否則其值為 `0`。

  若未給定 k 或其值為 `None`，則 k 值預設為 n，且函式回傳 `n!`。

  當任一參數非整數型別時會引發 `TypeError`。當任一參數為負數時會引發 `ValueError`。

  在 3.8 版被加入.

## 浮點數算術運算

math.ceil(x)

  回傳 x 經上取整的值，即大於或等於 x 的最小整數。若 x 並非浮點數，此函式將委派給 `x.__ceil__`，並回傳 `Integral` 型別的值。

math.fabs(x)

  回傳 x 的絕對值。

math.floor(x)

  回傳 x 經下取整的值，即小於或等於 x 的最大整數。若 x 並非浮點數，此函式將委派給 `x.__floor__`，並回傳 `Integral` 型別的值。

math.fma(x, y, z)

  融合乘加運算。回傳 `(x * y) + z`，用近似於無限精密度及範圍的方式計算，而後一次轉換為 `float` 格式。此操作通常能提供比運算式 `(x * y) + z` 更高的精確度。

  此函式遵循 IEEE-754 標準中規範的融合乘加（fusedMultiplyAdd）運算。該標準保留一種由實作決定的案例，即 `fma(0, inf, nan)` 和 `fma(inf, 0, nan)` 的結果；在這些案例中，`math.fma` 回傳 NaN 且不會引發例外。

  在 3.13 版被加入.

math.fmod(x, y)

  回傳 `x / y` 的浮點數餘數，其以平臺上的 C 函式庫 `fmod(x, y)` 函式定義。請注意此函式與 Python 運算式 `x % y` 可能不會回傳相同結果。C 標準要求 `fmod(x, y)` 的回傳值完全等同（數學定義上，即無限精密度）於 `x - n*y`，n*為可使回傳值與 *x 同號且量值小於 `abs(y)` 的整數。Python 運算式 `x % y` 的回傳值則與 y 同號，且可能無法精確地計算浮點數引數。例如：`fmod(-1e-100, 1e100)` 的值為 `-1e-100`，但 Python 運算式 `-1e-100 % 1e100` 的結果為 `1e100-1e-100`，此值無法準確地表示成浮點數，並會四捨五入為出乎意料的 `1e100`。因此，處理浮點數時通常會選擇函式 `fmod()`，而處理整數時會選擇 Python 運算式 `x % y`。

math.modf(x)

  回傳 x 的小數及整數部分，兩者皆為與 x 同號的浮點數。

  請注意 `modf()` 的呼叫/回傳模式與 C 語言中相應的函式不同：它們接受一個引數並回傳一對值，而非透過一個「輸出參數（output parameter）」傳遞第二個回傳值（Python 沒有那種東西）。

math.remainder(x, y)

  回傳 x 對 y 根據 IEEE 754 定義的餘數。對有限數 x 及有限非零數 y，該值為 `x - n*y` 差值，`n` 是最接近商數 `x / y` 的整數。若 `x / y` 剛好位於兩個連續整數的正中間，`n` 為最接近的偶數。因此該餘數 `r = remainder(x, y)` 總是滿足 `abs(r) <= 0.5 * abs(y)`。

  特殊情況遵循 IEEE 754：特別是，對任何有限數 x，`remainder(x, math.inf)` 的值為 x；對任何非 NaN 值的 x，`remainder(x, 0)` 及 `remainder(math.inf, x)` 會引發 `ValueError`。若取餘數操作的結果為零，則該零值會與 x 同號。

  在使用 IEEE 754 浮點標準中二進制浮點數的平台上，此操作的結果必能精準表示，不會出現捨入誤差。

  在 3.7 版被加入.

math.trunc(x)

  回傳去除小數部分而僅餘整數部分的 x。此函式會向零捨入：若 x 為正值，`trunc()` 等價於 `floor()`；若 x 為負值，`trunc()` 等價於 `ceil()`。若 x 非浮點數，此函式將委派給 `x.__trunc__`，而後回傳一 `Integral` 值。

使用 `ceil()`、`floor()` 及 `modf()` 三個函式時，請注意所有足夠大的浮點數都是精確的整數。Python 的浮點數型別的精密度通常不會超過 53 位元（與 C 語言 double 型別相同），因此當浮點數 x 滿足 `abs(x) >= 2**52` 時，它必然沒有小數部分。

## 浮點數操作函式

math.copysign(x, y)

  回傳與 x 相同量值（絕對值）且與 y 同號的浮點數。在支援帶符號零的平臺上，`copysign(1.0, -0.0)` 回傳 -1.0。

math.frexp(x)

  以 `(m, e)` 對的格式回傳 x 的尾數 m 及指數 e。m 是浮點數而 e 是整數，且兩者精確地使 `x == m * 2**e`。若 x 為零，回傳 `(0.0, 0)`，否則令 `0.5 <= abs(m) < 1`。此函式用於以可攜的方式「分割」浮點數內部表示法。

  請注意 `frexp()` 的呼叫/回傳模式與 C 語言中相應的函式不同：它們接受一個引數並回傳一對值，而非透過一個「輸出參數（output parameter）」傳遞第二個回傳值（Python 沒有那種東西）。

math.isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)

  若 a 及 b 兩值足夠接近便回傳 `True`，否則回傳 `False`。

  兩數是否足夠接近取決於給定的絕對及相對容許偏差 (tolerance)。如果沒有錯誤發生，結果將為：`abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)`。

  rel_tol 為相對容許偏差 ── a 與 b 兩數差的最大容許值，與 a 及 b 兩數的絕對值中較大者相關。例如欲設置 5% 的容許偏差，則傳入 `rel_tol=0.05`。其預設值為 `1e-09`，該值可確保兩數於大約 9 個十進數位內相同。rel_tol 須不為負且小於 `1.0`。

  abs_tol 為絕對容許偏差；預設為 `0.0` 且必須不為負。當比較 `x` 與 `0.0` 時，`isclose(x, 0)` 將計算為 `abs(x) <= rel_tol * abs(x)`，此結果對任何非零 `x` 及小於 `1.0` 的 rel_tol 而言皆為 `False`。因此呼叫時應加上適當的正數 abs_tol 引數。

  定義於 IEEE 754 浮點標準中的特殊值 `NaN`、`inf` 和 `-inf` 會根據該標準處理。更明確地說，`NaN` 不會與包含自身在內的任何數字足夠接近，而 `inf` 及 `-inf` 皆只與自身接近。

  在 3.5 版被加入.

  也參考

  PEP 485 ── 用於測試近似相等的函式

math.isfinite(x)

  若 x 不是無限值或 NaN 便回傳 `True`，否則回傳 `False`。（注意 `0.0` 被視為有限數。）

  在 3.2 版被加入.

math.isinf(x)

  若 x 是正無限值或負無限值便回傳 `True`，否則回傳 `False`。

math.isnan(x)

  若 x 是 NaN ── 即非數值（NaN, not a number）── 便回傳 `True`，否則回傳 `False`。

math.ldexp(x, i)

  回傳 `x * (2**i)`。此函式本質上為 `frexp()` 的反函式。

math.nextafter(x, y, steps=1)

  回傳 x 向 y steps 步的浮點數值。

  除非 steps 為零，否則當 x 與 y 相等時回傳 y。

  範例：

  - `math.nextafter(x, math.inf)` 增加：往正無限。

  - `math.nextafter(x, -math.inf)` 減少：往負無限。

  - `math.nextafter(x, 0.0)` 靠近零。

  - `math.nextafter(x, math.copysign(math.inf, x))` 遠離零。

  另請參閱 `math.ulp()`。

  在 3.9 版被加入.

  在 3.12 版的變更: 新增 steps 引數。

math.ulp(x)

  回傳浮點數 x 的最低有效位元：

  - 若 x 為 NaN（非數值），回傳 x。

  - 若 x 為負值，回傳 `ulp(-x)`。

  - 若 x 為正無限值，回傳 x。

  - 若 x 等於零，回傳反正規化可表示的最小正浮點數（此值小於正規化可表示的最小正浮點數 `sys.float_info.min`）。

  - 若 x 等於可表示的最大正浮點數，回傳 x 的最低有效位元值，使 `x-ulp(x)` 為第一個小於 x 的浮點數。

  - 否則（當 x 為正有限數），回傳 x 的最低有效位元值，使 `x+ulp(x)` 為第一個大於 x 的浮點數。

  ULP 即最後一位上的單位值（Unit in the Last Place）。

  另請參閱 `math.nextafter()` 及 `sys.float_info.epsilon`。

  在 3.9 版被加入.

## 次方、指數與對數函式

math.cbrt(x)

  回傳 x 的立方根。

  在 3.11 版被加入.

math.exp(x)

  回傳 e 的 x 次方，其中 e = 2.718281... 為自然對數的底數。此函式通常比 `math.e ** x` 或 `pow(math.e, x)` 更為精確。

math.exp2(x)

  回傳 2 的 x 次方。

  在 3.11 版被加入.

math.expm1(x)

  回傳 e 的 x 次方減 1。此處 e 為自然對數的底數。對於較小的浮點數 x，`exp(x) - 1` 中的減法運算可能導致顯著的精密度損失；`expm1()` 函式提供了一種能以完整精密度計算此值的方法：

      >>> from math import exp, expm1
      >>> exp(1e-5) - 1  # gives result accurate to 11 places
      1.0000050000069649e-05
      >>> expm1(1e-5)    # result accurate to full precision
      1.0000050000166668e-05

  在 3.2 版被加入.

math.log(x[, base])

  傳入一個引數時，回傳 x 的自然對數（以 e 為底）。

  傳入兩個引數時，回傳 x 以給定 base 為底的對數，計算方式為 `log(x)/log(base)`。

math.log1p(x)

  回傳 1+x 的自然對數（以 e 為底）。計算結果對於接近零的 x 值是精確的。

math.log2(x)

  回傳 x 的以 2 為底的對數。此函式通常比 `log(x, 2)` 更為精確。

  在 3.3 版被加入.

  也參考

  `int.bit_length()` 回傳以二進位表示一個整數所需的位元數，不包含正負號及前導零。

math.log10(x)

  回傳 x 的以 10 為底的對數。此函式通常比 `log(x, 10)` 更為精確。

math.pow(x, y)

  回傳 x 的 y 次方。例外情況盡可能遵循 IEEE 754 標準。特別是，`pow(1.0, x)` 和 `pow(x, 0.0)` 總是回傳 `1.0`，即使 x 是零或 NaN 也是如此。若 x 和 y 皆為有限數、x 為負數且 y 不是整數，則 `pow(x, y)` 是未定義的，並會引發 `ValueError`。

  與內建 `**` 運算子不同，`math.pow()` 會將其兩個引數都轉換為 `float` 型別。若需要計算精確的整數次方，請使用 `**` 或內建的 `pow()` 函式。

  在 3.11 版的變更: 特殊情況 `pow(0.0, -inf)` 和 `pow(-0.0, -inf)` 已變更為回傳 `inf` 而非引發 `ValueError`，以符合 IEEE 754 標準。

math.sqrt(x)

  回傳 x 的平方根。

## 總和與乘積函式

math.dist(p, q)

  回傳兩點 p 與 q 之間的歐幾里得距離，各點以座標的序列（或可疊代物件）表示。兩點必須具有相同的維度。

  約等價於：

      sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))

  在 3.8 版被加入.

math.fsum(iterable)

  回傳可疊代物件（iterable）中所有值的精確浮點數和。透過追蹤過程中多個部分和（partial sum）以避免精密度損失。

  此演算法準確性奠基於保證 IEEE-754 浮點標準及典型奇進偶捨（half-even）模式。於有些非 Windows 平台建置時，底層 C 函式庫使用延伸精密度加法運算，而可能導致對過程中同一部分和重複捨入，並使其最低有效位不如預期。

  更深入的討論及兩種替代做法請參閱 ASPN cookbook recipes 精準的浮點數總和。

math.hypot(*coordinates)

  回傳歐幾里得範數 `sqrt(sum(x**2 for x in coordinates))`。這是從原點到座標所給定的點之間的向量長度。

  對於二維點 `(x, y)`，這等同於使用畢氏定理計算直角三角形的斜邊，即 `sqrt(x*x + y*y)`。

  在 3.8 版的變更: 新增對 n 維點的支援。先前僅支援二維情況。

  在 3.10 版的變更: 改進了演算法的精確度，使最大誤差低於 1 ulp（最後一位上的單位值）。更典型的情況是，結果幾乎總是能正確捨入到 1/2 ulp 以內。

math.prod(iterable, *, start=1)

  計算輸入 iterable 中所有元素的乘積。乘積的預設 start 起始值為 `1`。

  當可疊代物件為空時，回傳起始值。此函式專門設計用於數值運算，可能會拒絕非數值型別。

  在 3.8 版被加入.

math.sumprod(p, q)

  回傳兩個可疊代物件 p 及 q 各值乘積的總和。

  若兩個傳入物件長度不同會引發 `ValueError`。

  約等價於：

      sum(map(operator.mul, p, q, strict=True))

  對浮點數或混合整數及浮點數的傳入物件，其過程中的乘積及總和皆使用延伸精密度計算。

  在 3.12 版被加入.

## 角度轉換

math.degrees(x)

  將角度 x 從弧度轉換為度。

math.radians(x)

  將角度 x 從度轉換為弧度。

## 三角函式

math.acos(x)

  回傳 x 的反餘弦值，以弧度表示。結果介於 `0` 與 `pi` 之間。

math.asin(x)

  回傳 x 的反正弦值，以弧度表示。結果介於 `-pi/2` 與 `pi/2` 之間。

math.atan(x)

  回傳 x 的反正切值，以弧度表示。結果介於 `-pi/2` 與 `pi/2` 之間。

math.atan2(y, x)

  回傳 `atan(y / x)`，以弧度表示。結果介於 `-pi` 與 `pi` 之間。從原點到點 `(x, y)` 的平面向量與正 X 軸形成此角度。`atan2()` 的重點在於它知道兩個輸入的正負號，因此能計算出角度所在的正確象限。例如，`atan(1)` 和 `atan2(1, 1)` 都是 `pi/4`，但 `atan2(-1, -1)` 是 `-3*pi/4`。

math.cos(x)

  回傳 x 弧度的餘弦值。

math.sin(x)

  回傳 x 弧度的正弦值。

math.tan(x)

  回傳 x 弧度的正切值。

## 雙曲函式

雙曲函式是三角函式的類似物，但基於雙曲線而非圓。

math.acosh(x)

  回傳 x 的反雙曲餘弦值。

math.asinh(x)

  回傳 x 的反雙曲正弦值。

math.atanh(x)

  回傳 x 的反雙曲正切值。

math.cosh(x)

  回傳 x 的雙曲餘弦值。

math.sinh(x)

  回傳 x 的雙曲正弦值。

math.tanh(x)

  回傳 x 的雙曲正切值。

## 特殊函式

math.erf(x)

  回傳在 x 處的誤差函式值。

  `erf()` 函式可用於計算傳統的統計函式，例如累積標準常態分布：

      def phi(x):
          '標準常態分布的累積分布函式'
          return (1.0 + erf(x / sqrt(2.0))) / 2.0

  在 3.2 版被加入.

math.erfc(x)

  回傳在 x 處的互補誤差函式值。互補誤差函式定義為 `1.0 - erf(x)`。此函式用於較大的 x 值，因為在該情況下從一減去會導致顯著性損失。

  在 3.2 版被加入.

math.gamma(x)

  回傳在 x 處的 Gamma 函式值。

  在 3.2 版被加入.

math.lgamma(x)

  回傳在 x 處 Gamma 函式絕對值的自然對數。

  在 3.2 版被加入.

## 常數

math.pi

  數學常數 π = 3.141592...，精確至可用精密度。

math.e

  數學常數 e = 2.718281...，精確至可用精密度。

math.tau

  數學常數 τ = 6.283185...，精確至可用精密度。Tau 是一個圓常數，等於 2π，即圓的周長與半徑的比值。若想了解更多關於 Tau 的資訊，請觀看 Vi Hart 的影片 Pi is (still) Wrong，並開始慶祝 Tau 日，吃兩倍的派吧！

  在 3.6 版被加入.

math.inf

  浮點數正無限值。（對於負無限值，請使用 `-math.inf`。）等同於 `float('inf')` 的輸出。

  在 3.5 版被加入.

math.nan

  浮點數「非數值」（NaN）值。等同於 `float('nan')` 的輸出。根據 IEEE-754 標準的要求，`math.nan` 和 `float('nan')` 不被認為等於任何其他數值，包括它們自身。若要檢查一個數是否為 NaN，請使用 `isnan()` 函式而非 `is` 或 `==`。範例：

      >>> import math
      >>> math.nan == math.nan
      False
      >>> float('nan') == float('nan')
      False
      >>> math.isnan(math.nan)
      True
      >>> math.isnan(float('nan'))
      True

  在 3.5 版被加入.

  在 3.11 版的變更: 現在總是可用。

CPython 實作細節： The `math` module consists mostly of thin wrappers around the platform C math library functions. Behavior in exceptional cases follows Annex F of the C99 standard where appropriate. The current implementation will raise `ValueError` for invalid operations like `sqrt(-1.0)` or `log(0.0)` (where C99 Annex F recommends signaling invalid operation or divide-by-zero), and `OverflowError` for results that overflow (for example, `exp(1000.0)`). A NaN will not be returned from any of the functions above unless one or more of the input arguments was a NaN; in that case, most functions will return a NaN, but (again following C99 Annex F) there are some exceptions to this rule, for example `pow(float('nan'), 0.0)` or `hypot(float('nan'), float('inf'))`.

請注意，Python 不會區分訊號型 NaN（signaling NaN）與安靜型 NaN（quiet NaN），且訊號型 NaN 的行為仍未指定。典型的行為是將所有 NaN 視為安靜型 NaN。

也參考

`cmath` 模組

  這些函式的複數版本。