<cmath>ヘッダでは、一般的な数学関数および各種マクロを提供する。
- 標準Cライブラリとの差異
- エラーの扱い
- エラーの種類
- 三角関数
- 双曲線関数
- 指数関数と対数関数
- 仮数と指数
- 累乗・冪根と絶対値
- 誤差関数とガンマ関数
- その他特殊関数
- 最近傍整数
- 剰余
- 浮動小数点操作
- 最大値・最小値と正の差
- 乗算・加算
- 線形補完
- 数値分類
- 数値比較
- 型
- 数値のマクロ
- 数値分類のマクロ
- その他のマクロ
標準Cライブラリとの差異
<cmath>は基本的には、標準 C ライブラリの <math.h> に準拠しているが、いくつかの変更点がある。
C++03のC90との差異
- 各関数は std 名前空間に定義されている。
fabsと等価の関数absを追加している。powの第 2 引数がintのオーバーロードを追加している。- 各関数(上記 2 関数を含む)に対して、引数および戻り値の
doubleに対応する箇所がfloatおよびlong doubleになっているオーバーロードバージョンを追加している。
C++11のC99との差異
- 各関数は std 名前空間に定義されている。
fabsと等価の関数absを追加している。- 引数に
doubleを含む各関数(上記absを含む)に対して、引数および戻り値のdoubleに対応する箇所がfloatとlong doubleのオーバーロードバージョンを追加している。
なお、C99 にも同様の関数(接尾辞がfおよびlのもの)が存在するが、それらについては規格書では言及されていない。
ただし、nanについては、引数の型では区別がつかないため、C99 のnanfおよびnanlをそのまま使用する。 - 数値分類、および、数値比較の各マクロの替わりに、引数が各浮動小数点型で、戻り値が
boolの関数を追加している。 -
上記に加えて、以下のようなオーバーロード解決ができるように、更にオーバーロードを追加している。
double型の仮引数に対応する実引数のいずれかがlong doubleである場合、double型の仮引数に対応する全ての実引数をlong doubleにキャストしてからオーバーロード解決を行う。- 上記以外で、
double型の仮引数に対応する実引数のいずれかがdouble型または整数型である場合、double型の仮引数に対応する全ての実引数をdoubleにキャストしてからオーバーロード解決を行う。 - 上記以外の場合、
double型の仮引数に対応する全ての実引数をfloatにキャストしてからオーバーロード解決を行う。
これらの規則は、C99 で導入された
<tgmath.h>の type-generic マクロとほぼ等価であるが、以下の点が異なる。- C99 では
modfは type-generic マクロの対象ではないが、C++11 ではオーバーロード解決の対象である。 - C99 では列挙型も整数型とみなされるが、C++11 では列挙型は(スコープ付き・スコープ無し共に)整数型とはみなされない。
- C++ のクラス型は変換演算子を持つことができるため、実引数の型が変換演算子を持つクラス型の場合も上記に従ってオーバーロード解決が行われる。
しかし、上記のオーバーロード解決の規則に厳密に従うと、列挙型や変換演算子を持つクラス型の引数が
floatと等価の扱いになってしまう。
このため、上記に記載のある無条件の「キャスト」は、C++14 ではその対象が「算術型」のみに限られることになり、列挙型や変換演算子を持つクラス型は上記の「キャスト」の対象とはならなくなった。
(もちろん、オーバーロード解決の後の暗黙の変換は依然として有効であるため、スコープ無し列挙型やexplicitでない変換演算子を持つクラス型は、明示的なキャスト無しで実引数になり得る。)
なお、C++11 の記載にある無条件のキャストは規格のバグとされたため、C++11 であってもスコープ付き列挙型や explicit な変換演算子のあるクラス型に、上記規則にある無条件のキャストが適用されると想定すべきではない。
(LWG 2086. Overly generic type support for math functions 参照)各関数の個別ページでは、上記のオーバーロード関数をコードで示す際には、引数や戻り値の型を斜体で示す。
Integral // 任意の整数型 Arithmetic // 任意の算術型 Promoted // 決定された戻り値型複数の引数がある場合には、数字のサフィックスで区別する。 例を以下に示す。
double atan(Integral x); Promoted atan2(Arithmetic1 y, Arithmetic2 x);
C++23での差異
constexpr対応
C++23では、多くの数学関数がconstexprに対応し、定数式内で使用できるようになった。C++23時点では、コンパイラベンダの負担が少ない機能をconstexpr対応した。
C++23でconstexpr対応する関数の条件は以下:
- 有理数の集合、または実数のどこにも密でない部分集合に作用すると見なされ、関数が閉じていること
- 関数が丸めモードに強く依存しないこと
exp()、log()、sqrt()、cos()、sin()は1. の条件を満たさないため、C++23ではconstexprに対応しない。
nearbyint()は2. の条件を満たさないため、C++23ではconstexprに対応しない。
ただし、コンパイラが先行してconstexpr非対応の関数も対応している可能性がある。
なお、C++20ではlerp()のみconstexprに対応している。これはC標準ライブラリからの移植ではなく、C++で標準化された関数だからである (errnoや浮動小数点例外のようなグローバル状態を使用しない)。
拡張浮動小数点数型への対応
C++23では<stdfloat>に拡張浮動小数点数型が追加された。その対応として、以下のようなfloat、double、long doubleに対するオーバーロードは、
float abs(float x);
double abs(double x);
long double abs(long double x);
以下のようにfloating-point-typeへのオーバーロードに統合され、拡張浮動小数点数型も扱えるようになった。
floating-point-type abs(floating-point-type x);
エラーの扱い
<cmath> で提供される各関数は、特に明記されていない限り、引数の型が表現できる全ての値についての挙動が定義されている。
なお、ここで言う「挙動が定義されている」とは、未定義動作を引き起こさないというだけで、エラーが発生したり、実装依存の挙動となる場合がある事に注意。
<cmath> で提供される各関数においてエラーが発生した場合、errno、あるいは、浮動小数点例外のいずれか、もしくは両方によってエラーが通知される。
C++11 以降の場合、どちらの方法によって通知されるかは math_errhandling の値によって判別可能である。(利用者が選択する事はできない)
C++03 までの場合、errno でしか通知されない。
errno によるエラーの通知
errno によってエラーが通知される場合、エラー内容は errno に設定された値によって判別可能である。
なお、エラーが発生しなかった場合でも errno がクリアされる事は無いので、エラー発生の有無を errno で判断するためにはあらかじめ errno にゼロを設定しておく必要がある。
浮動小数点例外によるエラーの通知(C++11 以降)
名称に「例外」と付いているが、C++ の例外とは全く関係ないため注意。
浮動小数点例外によってエラーが通知される場合、エラー内容は浮動小数点状態フラグに設定されるため、fetestexcept によって判別可能である。
なお、エラーが発生しなかった場合でも浮動小数点状態フラグがクリアされる事は無いので、エラー発生の有無を浮動小数点状態フラグで判断するためにはあらかじめ feclearexcept で浮動小数点状態フラグをクリアしておく必要がある。
エラーの種類
<cmath> で提供される各関数で発生するエラーは、以下の 5 種類ある。
定義域エラー(domain error)
引数の値が、関数の数学的な定義域の範囲外であることを示すエラー。(例:sqrt(-1.0) や、asin(2.0) 等)
定義域エラーが発生しなければならない条件は関数毎に規格で規定されているが、数学的な定義と整合的である場合には追加の条件で定義域エラーが発生する事が処理系に許されている。
定義域エラーが発生した場合、通知は以下のように行われる。
errnoによってエラーが通知される場合、EDOM(定義域エラー、Error DOMain)が設定される。- 浮動小数点例外によってエラーが通知される場合、
FE_INVALID(無効演算浮動小数点例外)が設定される。
定義域エラーが発生した場合、関数の戻り値は処理系定義であるが、戻り値の型が quiet NaN(quiet Not a Number:静かな非数)を表現可能(std::numeric_limits<T>::has_quiet_NaN が真)の場合、一般的には quiet NaN が返る。
極エラー(pole error)
引数の値が有限値である場合に、関数の当該値に対する数学的な極限値が無限大であることを示すエラー。(例:log(0.0) や、atanh(1.0) 等)
引数の値が無限大の場合には、極エラーではないので注意。
極エラーが発生しなければならない条件は関数毎に規格で規定されているが、数学的な定義と整合的である場合には追加の条件で極エラーが発生する事が処理系に許されている。
極エラーが発生した場合、通知は以下のように行われる。
errnoによってエラーが通知される場合、ERANGE(値域エラー、Error RANGE)が設定される。- 浮動小数点例外によってエラーが通知される場合、
FE_DIVBYZERO(ゼロ除算浮動小数点例外)が設定される(注:「ゼロ除算浮動小数点例外」は誤記では無い)。
極エラーが発生した場合、関数の戻り値は処理系定義であるが、戻り値の型が浮動小数点数の場合、一般的には HUGE_VAL(double)、HUGE_VALF(float 、C++11 以降のみ)、HUGE_VALL(long double、C++11 以降のみ)に正しい符号を付加した値が返る。
また、戻り値の型が無限大を表現可能(std::numeric_limits<T>::has_infinity が真)の場合、一般的には無限大(std::numeric_limits<T>::infinity())が返る。
なお、マクロ INFINITY も、定義されている場合には無限大を表すものではあるが、float 型であることに注意。
オーバーフローエラー(overflow error)
戻り値が有限だが大きすぎるため、余分な丸め誤差無しでは戻り値の型で表す事が出来ないことを示すエラー。
オーバーフローエラーが発生した場合、通知は以下のように行われる。
errnoによってエラーが通知される場合、ERANGE(値域エラー、Error RANGE)が設定される。- 浮動小数点例外によってエラーが通知される場合、
FE_OVERFLOW(オーバーフロー浮動小数点例外)が設定される。
オーバーフローエラーが発生した場合、戻り値の型が浮動小数点型でデフォルトの丸めモードが有効であれば、HUGE_VAL(double)、HUGE_VALF(float 、C++11 以降のみ)、HUGE_VALL(long double、C++11 以降のみ)に正しい符号を付加した値が返る。
アンダーフローエラー(underflow error)
戻り値の絶対値が小さすぎるため、余分な丸め誤差無しでは戻り値の型で表す事が出来ないことを示すエラー。
アンダーフローエラーが発生した場合でも処理系によってはエラーの通知が行われないが(規格でエラーの通知が任意となっているため)、通知される場合には以下のように行われる。
errnoによってエラーが通知される場合、ERANGE(値域エラー、Error RANGE)が設定される。- 浮動小数点例外によってエラーが通知される場合、
FE_UNDERFLOW(アンダーフロー浮動小数点例外)が設定される。
アンダーフローエラーが発生した場合、関数の戻り値は処理系定義であるが、戻り値の絶対値はその型における最小の正の正規化数(std::numeric_limits<T>::min())以下である。(非正規化数、あるいは、ゼロを含む)
不正確エラー(inexact error)
戻り値が戻り値の型では正確に表す事が出来ないことを示すエラー。(例:exp(1.0) や、sqrt(2.0) 等)
浮動小数点演算ではほとんどの場合に発生する。
不正確エラーが発生した場合でも処理系によってはエラーの通知が行われないが(規格でエラーの通知が任意となっているため)、通知される場合には以下のように行われる。
errnoによるエラーの通知は行われない。- 浮動小数点例外によってエラーが通知される場合、
FE_INEXACT(不正確浮動小数点例外)が設定される。
不正確エラーが発生した場合、関数の戻り値は真の値を丸めた値となるが、その際の丸め方式は処理系定義である。(関数に特別に規定がある場合を除く)
特に、fesetround で設定した丸め方式に従うとは限らないため、注意が必要である。
定数式になる条件
constexpr対応する数学関数において、以下のいずれかの条件に合致する場合、定数式とならない (引数によってコンパイルエラーになる)
FE_INEXACT以外の、以下の浮動小数点例外が発生した場合:FE_DIVBYZERO(ゼロ除算)FE_INVALID(不正な演算)FE_OVERFLOW(オーバーフロー)FE_UNDERFLOW(アンダーフロー)
math_errhandling & MATH_ERRNOが真で、errnoが設定された場合
三角関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
sin |
正弦関数(サイン) | |
cos |
余弦関数(コサイン) | |
tan |
正接関数(タンジェント) | |
asin |
逆正弦関数(アークサイン) | |
acos |
逆余弦関数(アークコサイン) | |
atan |
逆正接関数(アークタンジェント) | |
atan2 |
対辺と隣辺からの逆正接関数(アークタンジェント) |
双曲線関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
sinh |
双曲線正弦関数(ハイパボリックサイン) | |
cosh |
双曲線余弦関数(ハイパボリックコサイン) | |
tanh |
双曲線正接関数(ハイパボリックタンジェント) | |
asinh |
逆双曲線正弦関数(エリアハイパボリックサイン) | C++11 |
acosh |
逆双曲線余弦関数(エリアハイパボリックコサイン) | C++11 |
atanh |
逆双曲線正接関数(エリアハイパボリックタンジェント) | C++11 |
指数関数と対数関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
exp |
e (ネイピア数) を底とする指数関数 | |
exp2 |
2 を底とする指数関数 | C++11 |
expm1 |
e (ネイピア数) を底とする指数関数から 1 を引いた値 | C++11 |
log |
e (ネイピア数) を底とする自然対数 | |
log10 |
10 を底とする常用対数 | |
log1p |
引数に 1 を足した値の、e (ネイピア数) を底とする自然対数 | C++11 |
log2 |
2 を底とする二進対数 | C++11 |
仮数と指数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
ldexp |
2 の累乗との乗算 | |
frexp |
仮数部と 2 の累乗への分解 | |
ilogb |
指数部を符号付き整数値として抽出 | C++11 |
logb |
指数部を浮動小数点数値として抽出 | C++11 |
modf |
整数部と小数部への分解 | |
scalbn |
内部表現の基数 (FLT_RADIX) の累乗との乗算 |
C++11 |
scalbln |
内部表現の基数 (FLT_RADIX) の累乗との乗算。乗数としてlongをとる |
C++11 |
累乗・冪根と絶対値
| 名前 | 説明 | 対応バージョン |
|---|---|---|
pow |
累乗 | |
sqrt |
平方根 | |
cbrt |
立方根 | C++11 |
hypot |
平方和の平方根 | C++11 |
abs |
絶対値 | |
fabs |
絶対値 |
誤差関数とガンマ関数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
erf |
誤差関数 | C++11 |
erfc |
相補誤差関数 | C++11 |
tgamma |
ガンマ関数 | C++11 |
lgamma |
ガンマ関数の自然対数 | C++11 |
その他特殊関数
以下の関数は引数に NaN が渡された場合、 NaN を返さなければならないが定義域エラーを報告してはならない。 引数が NaN ではないが次の条件を一つでも満たす場合、定義域エラーを報告しなければならない:
- 規格が関数の定義域を明示していて (各解説ページを参照)、その定義域内にない
- 数学関数の値の虚部が 0 でない
- 数学関数が数学的に定義されていない
数学関数が数学的に定義されるのは以下のいずれかの場合である:
- ある集合において明示的に定義されている
- 極限が存在する (右極限と左極限が存在し、一致する)
特記のない限り、以下の関数は全ての有限値と正負の無限大において定義される。
| 名前 | 説明 | 対応バージョン |
|---|---|---|
assoc_laguerre |
ラゲール陪多項式 | C++17 |
assoc_legendre |
ルジャンドル陪関数 | C++17 |
beta |
ベータ関数 | C++17 |
comp_ellint_1 |
第1種完全楕円積分 | C++17 |
comp_ellint_2 |
第2種完全楕円積分 | C++17 |
comp_ellint_3 |
第3種完全楕円積分 | C++17 |
cyl_bessel_i |
第1種変形ベッセル関数 | C++17 |
cyl_bessel_j |
第1種ベッセル関数 | C++17 |
cyl_bessel_k |
第2種変形ベッセル関数 | C++17 |
cyl_neumann |
第2種ベッセル関数 | C++17 |
ellint_1 |
第1種不完全楕円積分 | C++17 |
ellint_2 |
第2種不完全楕円積分 | C++17 |
ellint_3 |
第3種不完全楕円積分 | C++17 |
expint |
指数積分 | C++17 |
hermite |
エルミート多項式 | C++17 |
laguerre |
ラゲール多項式 | C++17 |
legendre |
ルジャンドル多項式 | C++17 |
riemann_zeta |
リーマンのゼータ関数 | C++17 |
sph_bessel |
第1種球ベッセル関数 | C++17 |
sph_legendre |
球面調和関数の θ 成分 | C++17 |
sph_neumann |
第2種球ベッセル関数 | C++17 |
最近傍整数
| 名前 | 説明 | 対応バージョン |
|---|---|---|
ceil |
天井関数(引数より小さくない最近傍の整数) | |
floor |
床関数(引数より大きくない最近傍の整数) | |
trunc |
ゼロ方向への丸め | C++11 |
round |
四捨五入による丸め | C++11 |
lround |
long 型への四捨五入による丸め |
C++11 |
llround |
long long 型への四捨五入による丸め |
C++11 |
nearbyint |
現在の丸めモードによる丸め | C++11 |
rint |
現在の丸めモードによる丸め | C++11 |
lrint |
long 型への現在の丸めモードによる丸め |
C++11 |
llrint |
long long 型への現在の丸めモードによる丸め |
C++11 |
剰余
| 名前 | 説明 | 対応バージョン |
|---|---|---|
fmod |
浮動小数点剰余 | |
remainder |
符号付きの浮動小数点剰余 | C++11 |
remquo |
商と浮動小数点剰余 | C++11 |
浮動小数点操作
| 名前 | 説明 | 対応バージョン |
|---|---|---|
copysign |
符号のコピー | C++11 |
nan |
文字列から quiet NaN への変換 | C++11 |
nanf |
文字列から quiet NaN への変換 | C++11 |
nanl |
文字列から quiet NaN への変換 | C++11 |
nextafter |
指定方向への次の表現可能な値 | C++11 |
nexttoward |
指定方向への次の表現可能な値 | C++11 |
最大値・最小値と正の差
| 名前 | 説明 | 対応バージョン |
|---|---|---|
fmax |
最大値 (-0.0と+0.0では未規定、NaNと値では値を返す) |
C++11 |
fmin |
最小値 (-0.0と+0.0では未規定、NaNと値では値を返す) |
C++11 |
fmaximum |
最大値 (-0.0と+0.0では+0.0、NaNと値ではNaNを返す) |
C++26 |
fmaximum_num |
最大値 (-0.0と+0.0では+0.0、NaNと値では値を返す) |
C++26 |
fminimum |
最小値 (-0.0と+0.0では-0.0、NaNと値ではNaNを返す) |
C++26 |
fminimum_num |
最小値 (-0.0と+0.0では-0.0、NaNと値では値を返す) |
C++26 |
fdim |
正の差 | C++11 |
乗算-加算
| 名前 | 説明 | 対応バージョン |
|---|---|---|
fma |
乗算と加算の合成 | C++11 |
線形補完
| 名前 | 説明 | 対応バージョン |
|---|---|---|
lerp |
線形補間 | C++20 |
数値分類
| 名前 | 説明 | 対応バージョン |
|---|---|---|
fpclassify |
数値を NaN、無限大、正規化数、非正規化数、0 または他の処理系定義のカテゴリに分類 | C++11 |
isfinite |
数値が有限であるか判定 | C++11 |
isinf |
数値が無限大であるか判定 | C++11 |
isnan |
数値が NaN であるか判定 | C++11 |
isnormal |
数値が正規化数であるか判定 | C++11 |
signbit |
数値の符号が負であるか判定 | C++11 |
数値比較
| 名前 | 説明 | 対応バージョン |
|---|---|---|
isgreater |
第 1 引数が第 2 引数より大きいか判定 | C++11 |
isgreaterequal |
第 1 引数が第 2 引数以上か判定 | C++11 |
isless |
第 1 引数が第 2 引数より小さいか判定 | C++11 |
islessequal |
第 1 引数が第 2 引数以下か判定 | C++11 |
islessgreater |
第 1 引数が第 2 引数より小さいか、あるいは大きいか判定 | C++11 |
isunordered |
第 1 引数と第 2 引数が順序付けられていないか判定 | C++11 |
型
| 名前 | 説明 | 対応バージョン |
|---|---|---|
float_t |
float 以上の浮動小数点数型 |
C++11 |
double_t |
double 以上の浮動小数点数型 |
C++11 |
数値のマクロ
| 名前 | 説明 | 対応バージョン |
|---|---|---|
HUGE_VAL |
double 型の正の巨大値 |
|
HUGE_VALF |
float 型の正の巨大値 |
C++11 |
HUGE_VALL |
long double 型の正の巨大値 |
C++11 |
INFINITY |
float 型の正の無限大 |
C++11 |
NAN |
float 型の quiet NaN |
C++11 |
数値分類のマクロ
| 名前 | 説明 | 対応バージョン |
|---|---|---|
FP_INFINITE |
数値分類で無限大を表す整数定数式 | C++11 |
FP_NAN |
数値分類で NaN を表す整数定数式 |
C++11 |
FP_NORMAL |
数値分類で正規化数を表す整数定数式 | C++11 |
FP_SUBNORMAL |
数値分類で非正規化数を表す整数定数式 | C++11 |
FP_ZERO |
数値分類で浮動小数点数の 0 を表す整数定数式 | C++11 |
その他のマクロ
| 名前 | 説明 | 対応バージョン |
|---|---|---|
FP_FAST_FMA |
double 型の fma 関数がより高速な実装であるか |
C++11 |
FP_FAST_FMAF |
float 型の fma 関数がより高速な実装であるか |
C++11 |
FP_FAST_FMAL |
long double 型の fma 関数がより高速な実装であるか |
C++11 |
FP_ILOGB0 |
ilogb(0) の戻り値を表す整数定数式 |
C++11 |
FP_ILOGBNAN |
ilogb(NaN) の戻り値を表す整数定数式 |
C++11 |
MATH_ERRNO |
数学ライブラリ内でerrnoにエラーが設定されたかを表す整数定数 |
C++11 |
MATH_ERREXCEPT |
数学ライブラリ内で浮動小数点例外が発生したかを表す整数定数 | C++11 |
math_errhandling |
<cmath> 内の関数がエラーをどのように取り扱うかを表すマクロ |
C++11 |
関連項目
参照
- N1568 Proposed additions to TR-1 to improve compatibility with C99
- P0175R0 Synopses for the C library
- C++17 から
f、lサフィックス付きのC関数を導入
- C++17 から
- P0533R9 constexpr for
<cmath>and<cstdlib>- C++23での、一部関数の
constexpr対応
- C++23での、一部関数の