C++11の数学関数

この記事はC++11 Advent Calendar 2011の参加記事です。(書きかけ)

C++11には、C99の数学関数や浮動小数点数を扱う関数が追加されました。追加された関数のうち便利なものをいくつか紹介したいと思います。

C99との相違点

今回紹介する関数はC99由来のものですが、C++11への追加に際して変更があります。1つ目の変更は関数の名前です。Cでは関数のオーバーロードができないので、float用、double用、long double用の関数が別の名前を使わなければならないのに対し、C++では同じ名前で使えます。例えばC99のガンマ関数は

float tgammaf(float);
double tgamma(double);
long double tgammal(long double);

のようにfloat, long doubleのものには接尾辞が付いてしまいます。一方C++11のガンマ関数は

float tgamma(float);
double tgamma(double);
long double tgamma(long double);

のように同じ名前です。

2つ目の変更はC++複素数クラスへの対応です。C99ではC++のstd::complexとは異なる複素数型があり、複素数を扱う関数は当然その型を受け取ります。そういった関数をそのままC++に持ってくるだけでは不便なので、std::complexに対応したC99由来の関数がC++11に追加されています。

3つ目の変更は、C99ではマクロだったものがC++11では関数になったものがあることです。

の関数

双曲線関数

float acosh(float);
double acosh(double);
long double acosh(long double);

float asinh(float);
double asinh(double);
long double asinh(long double);

float atanh(float);
double atanh(double);
long double atanh(long double);

誤差関数

float erf(float);
double erf(double);
long double erf(long double);

float erfc(float);
double erfc(double);
long double erfc(long double);

ガンマ関数

float tgamma(float);
double tgamma(double);
long double tgamma(long double);

float lgamma(float);
double lgamma(double);
long double lgamma(long double);

その他の便利な数学関数

float cbrt(float);
double cbrt(double);
long double cbrt(long double);

float log2(float);
double log2(double);
long double log2(long double);

float logb(float);
double logb(double);
long double logb(long double);
int ilogb(float);
int ilogb(double);
int ilogb(long double);

fdim(x, y) = x > y ? x - y : 0

float fdim(float x, float y);
double fdim(double x, double y);
long double fdim(long double x, long double y);

fma(x, y, z) = x * y + z

float fma(float x, float y, float z);
double fma(double x, double y, double z);
long double fma(long double x, long double y, long double z);

float hypot(float x, float y);
double hypot(double x, double y);
long double hypot(long double x, long double y);

float scalbn(float x, int n);
double scalbn(double x, int n);
long double scalbn(long double x, int n);
float scalbln(float x, long n);
double scalbln(double x, long n);
long double scalbln(long double x, long n);

浮動小数点数の分類

bool isinfinite(float);
bool isinfinite(double);
bool isinfinite(long double);
bool isnormal(float);
bool isnormal(double);
bool isnormal(long double);
bool isinf(float);
bool isinf(double);
bool isinf(long double);
bool isnan(float);
bool isnan(double);
bool isnan(long double);
bool isunordered(float);
bool isunordered(double);
bool isunordered(long double);
int fpclassify(float);
int fpclassify(double);
int fpclassify(long double);
bool signbit(float);
bool signbit(double);
bool signbit(long double);

複素関数

リーマン球面への投影

template <typename T>
complex<T> proj(complex<T> const&);

template <typename T>
complex<T> acos(complex<T> const&);

template <typename T>
complex<T> asin(complex<T> const&);

template <typename T>
complex<T> atan(complex<T> const&):

template <typename T>
complex<T> acosh(complex<T> const&);

template <typename T>
complex<T> asinh(complex<T> const&);

template <typename T>
complex<T> atanh(complex<T> const&);