<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 |
最大値 | C++11 |
fmin |
最小値 | C++11 |
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
- P00175R0 Synopses for the C library
- C++17 から
f
、l
サフィックス付きのC関数を導入
- C++17 から
- P0533R9 constexpr for
<cmath>
and<cstdlib>
- C++23での、一部関数の
constexpr
対応
- C++23での、一部関数の