C++为我们提供了很多已经定义好的一些数学函数,这些函数的使用一定要注意函数的定义域,因为计算机表示的数据有限,有些非法的运算的结果也是在数值运算库中定义好了的。
在标准库中基本上提供了对于 float、double、long double 类型参数的输入、也有对应的参数 float、double、long double 的输出。就像下面的可以看得出来 不带 任何的后缀是有3个类型的重载、带 ‘f’ 的指定了强制 float 类型、带 ‘l’ 的强制指定了 long double 类型。基本上下面提到的函数都会有这些后缀以满足不同精度的需求。
float fmod ( float x, float y );
double fmod ( double x, double y );
long double fmod ( long double x, long double y );
float fmodf( float x, float y );
long double fmodl( long double x, long double y );
基础定义: 就是求一个数值的绝对值
double abs( double arg );
abs(float x)
fabs
fabsf
fabsl
此函数不受制于任何指定于 math_errhandling 的错误条件。
若实现支持 IEEE 浮点算术( IEC 60559 ),则
示例:
#include <iostream>
#include <cmath>
int main()
{
std::cout << "abs(+3.0) = " << std::abs(+3.0) << '\n'
<< "abs(-3.0) = " << std::abs(-3.0) << '\n';
// 特殊值
std::cout << "abs(-0.0) = " << std::abs(-0.0) << '\n'
<< "abs(-Inf) = " << std::abs(-INFINITY) << '\n'
<< "abs(-NaN) = " << std::abs(-NAN) << '\n';
}
//输出
abs(+3.0) = 3
abs(-3.0) = 3
abs(-0.0) = 0
abs(-Inf) = inf
abs(-NaN) = nan
基础定义:计算除法运算 x/y 的浮点余数。有点像整数的余数运算符 %
double fmod ( double x, double y );
fmod
fmodf
fmodl
#include <iostream>
#include <cmath>
#include <cfenv>
#pragma STDC FENV_ACCESS ON
int main()
{
std::cout << "fmod(+5.1, +3.0) = " << std::fmod(5.1,3) << '\n'
<< "fmod(-5.1, +3.0) = " << std::fmod(-5.1,3) << '\n'
<< "fmod(+5.1, -3.0) = " << std::fmod(5.1,-3) << '\n'
<< "fmod(-5.1, -3.0) = " << std::fmod(-5.1,-3) << '\n';
// 特殊值
std::cout << "fmod(+0.0, 1.0) = " << std::fmod(0, 1) << '\n'
<< "fmod(-0.0, 1.0) = " << std::fmod(-0.0, 1) << '\n'
<< "fmod(5.1, Inf) = " << std::fmod(5.1, INFINITY) << '\n';
// 错误处理
std::feclearexcept(FE_ALL_EXCEPT);
std::cout << "fmod(+5.1, 0) = " << std::fmod(5.1, 0) << '\n';
if(std::fetestexcept(FE_INVALID))
std::cout << " FE_INVALID raised\n";
}
// 输出
fmod(+5.1, +3.0) = 2.1
fmod(-5.1, +3.0) = -2.1
fmod(+5.1, -3.0) = 2.1
fmod(-5.1, -3.0) = -2.1
fmod(+0.0, 1.0) = 0
fmod(-0.0, 1.0) = -0
fmod(5.1, Inf) = 5.1
fmod(+5.1, 0) = -nan
FE_INVALID raised
基础定义:此函数所计算的除法运算 x/y 的 IEEE 浮点余数,准确地为值 x - n*y ,其中值 n 是最接近 x/y 准确值的整数值。 |n-x/y| = ? 时,选择作为偶数的 n 。与 std::fmod() 相反,不保证返回值拥有与 x 相同的符号。若返回值是 0 ,则它拥有与 x 相同的符号。
double remainder ( double x, double y );
remainder
remainderf
remainderl
#include <iostream>
#include <cmath>
#include <cfenv>
#pragma STDC FENV_ACCESS ON
int main()
{
std::cout << "remainder(+5.1, +3.0) = " << std::remainder(5.1,3) << '\n'
<< "remainder(-5.1, +3.0) = " << std::remainder(-5.1,3) << '\n'
<< "remainder(+5.1, -3.0) = " << std::remainder(5.1,-3) << '\n'
<< "remainder(-5.1, -3.0) = " << std::remainder(-5.1,-3) << '\n';
// 特殊值
std::cout << "remainder(-0.0, 1.0) = " << std::remainder(-0.0, 1) << '\n'
<< "remainder(5.1, Inf) = " << std::remainder(5.1, INFINITY) << '\n';
// 错误处理
std::feclearexcept(FE_ALL_EXCEPT);
std::cout << "remainder(+5.1, 0) = " << std::remainder(5.1, 0) << '\n';
if(fetestexcept(FE_INVALID))
std::cout << " FE_INVALID raised\n";
}
//输出
remainder(+5.1, +3.0) = -0.9
remainder(-5.1, +3.0) = 0.9
remainder(+5.1, -3.0) = -0.9
remainder(-5.1, -3.0) = 0.9
remainder(-0.0, 1.0) = -0
remainder(5.1, Inf) = 5.1
remainder(+5.1, 0) = -nan
FE_INVALID raised
基础定义:
remquo
remquof
remquol
基础定义:计算 (x*y) + z ,如同用无限精度,而仅舍入一次到结果类型。
double fma ( double x, double y, double z );
fma
fmaf
fmal
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cfenv>
#pragma STDC FENV_ACCESS ON
int main()
{
// 演示 fma 与内建运算符间的差别
double in = 0.1;
std::cout << "0.1 double is " << std::setprecision(23) << in
<< " (" << std::hexfloat << in << std::defaultfloat << ")\n"
<< "0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3), "
<< "or 1.0 if rounded to double\n";
double expr_result = 0.1 * 10 - 1;
double fma_result = fma(0.1, 10, -1);
std::cout << "0.1 * 10 - 1 = " << expr_result
<< " : 1 subtracted after intermediate rounding\n"
<< "fma(0.1, 10, -1) = " << std::setprecision(6) << fma_result << " ("
<< std::hexfloat << fma_result << std::defaultfloat << ")\n\n";
// fma 用于 double-double 算术
double high = 0.1 * 10;
double low = fma(0.1, 10, -high);
std::cout << "in double-double arithmetic, 0.1 * 10 is representable as "
<< high << " + " << low << "\n\n";
// 错误处理
std::feclearexcept(FE_ALL_EXCEPT);
std::cout << "fma(+Inf, 10, -Inf) = " << std::fma(INFINITY, 10, -INFINITY) << '\n';
if(std::fetestexcept(FE_INVALID))
std::cout << " FE_INVALID raised\n";
}
//输出
0.1 double is 0.10000000000000000555112 (0x1.999999999999ap-4)
0.1*10 is 1.0000000000000000555112 (0x8.0000000000002p-3), or 1.0 if rounded to double
0.1 * 10 - 1 = 0 : 1 subtracted after intermediate rounding
fma(0.1, 10, -1) = 5.55112e-17 (0x1p-54)
in double-double arithmetic, 0.1 * 10 is representable as 1 + 5.55112e-17
fma(+Inf, 10, -Inf) = -nan
FE_INVALID raised
基础定义:返回二个浮点数的较大者
double fmax ( double x, double y );
fmax
fmaxf
fmaxl
#include <iostream>
#include <cmath>
int main()
{
std::cout << "fmax(2,1) = " << std::fmax(2,1) << '\n'
<< "fmax(-Inf,0) = " << std::fmax(-INFINITY,0) << '\n'
<< "fmax(NaN,-1) = " << std::fmax(NAN,-1) << '\n';
}
//输出:
fmax(2,1) = 2
fmax(-Inf,0) = 0
fmax(NaN,-1) = -1
基础定义:返回二个浮点数的较小者
double fmin ( double x, double y );
fmin
fminf
fminl
#include <iostream>
#include <cmath>
int main()
{
std::cout << "fmin(2,1) = " << std::fmin(2,1) << '\n'
<< "fmin(-Inf,0) = " << std::fmin(-INFINITY,0) << '\n'
<< "fmin(NaN,-1) = " << std::fmin(NAN,-1) << '\n';
}
//输出
fmin(2,1) = 1
fmin(-Inf,0) = -inf
fmin(NaN,-1) = -1
基础定义:返回 x 与 y 间的正差,即若 x>y 则返回 x-y ,否则(若 x≤y )返回 +0 。
double fdim ( double x, double y );
fdim
fdimf
fdiml
#include <iostream>
#include <cmath>
#include <cerrno>
#include <cstring>
#include <cfenv>
#pragma STDC FENV_ACCESS ON
int main()
{
std::cout << "fdim(4, 1) = " << std::fdim(4, 1)
<< " fdim(1, 4) = " << std::fdim(1, 4) << '\n'
<< "fdim(4,-1) = " << std::fdim(4, -1)
<< " fdim(1,-4) = " << std::fdim(1, -4) << '\n';
// 错误处理
errno = 0;
std::feclearexcept(FE_ALL_EXCEPT);
std::cout << "fdim(1e308, -1e308) = " << std::fdim(1e308, -1e308) << '\n';
if (errno == ERANGE)
std::cout << " errno == ERANGE: " << std::strerror(errno) << '\n';
if (std::fetestexcept(FE_OVERFLOW))
std::cout << " FE_OVERFLOW raised\n";
}
//输出
fdim(4, 1) = 3 fdim(1, 4) = 0
fdim(4,-1) = 5 fdim(1,-4) = 5
fdim(1e308, -1e308) = inf
errno == ERANGE: Numerical result out of range
FE_OVERFLOW raised
基础定义
double exp ( double arg );
exp
expf
expl
图像
基础定义
double exp2 ( double n );
exp2
exp2f
exp2l
图像
基础定义:
double expm1 ( double arg );`在这里插入代码片`
expm1
expm1f
expm1l
图像
基础定义
double log ( double arg );
log
logf
logl
图像
基础定义
double log10 ( double arg );
log10
log10f
log10l
图像
基础定义
double log2 ( double arg );
log2
log2f
log2l
图像
基础定义
double log1p ( double arg );
log1p
log1pf
log1pl
图像
基础定义
double pow ( double base, double exp );
pow
powf
powl
基础定义
double sqrt ( double arg );
sqrt
sqrtf
sqrtl
基础定义
double cbrt ( double arg );
cbrt
cbrtf
cbrtl
基础定义
double hypot ( double x, double y );
hypot
hypotf
hypotl
基础定义
double sin ( double arg );
sin
sinf
sinl
图像
基础定义
double cos ( double arg );
cos
cosf
cosl
图像
基础定义
double tan ( double arg );
tan
tanf
tanl
图像
基础定义
double asin ( double arg );
asin
asinf
asinl
图像
基础定义
double acos ( double arg );
acos
acosf
acosl
图像
基础定义
double atan ( double arg );
atan
atanf
atanl
图像
基础定义
double atan2 ( double y, double x );
atan2
atan2f
atan2l
基础定义
double sinh ( double arg );
sinh
sinhf
sinhl
图像
基础定义
double cosh ( double arg );
cosh
coshf
coshl
图像
基础定义
double tanh ( double arg );
tanh
tanhf
tanhl
图像
基础定义
double asinh ( double arg );
asinh
asinhf
asinhl
图像
基础定义
double acosh ( double arg );
acosh
acoshf
acoshl
图像
基础定义
double atanh ( double arg );
atanh
atanhf
atanhl
图像
erf
erff
erfl
erfc
erfcf
erfcl
tgamma
tgammaf
tgammal
lgamma
lgammaf
lgammal
基础定义:计算不小于 arg 的最小整数值。
double ceil ( double arg );
ceil
ceilf
ceill
#include <cmath>
#include <iostream>
int main()
{
std::cout << std::fixed
<< "floor(+2.7) = " << std::floor(+2.7) << '\n'
<< "floor(-2.7) = " << std::floor(-2.7) << '\n'
<< "floor(-0.0) = " << std::floor(-0.0) << '\n'
<< "floor(-Inf) = " << std::floor(-INFINITY) << '\n';
}
//输出:
floor(+2.7) = 2.000000
floor(-2.7) = -3.000000
floor(-0.0) = -0.000000
floor(-Inf) = -inf
基础定义:计算不大于 arg 的最大整数值。
#include <cmath>
#include <iostream>
int main()
{
std::cout << std::fixed
<< "floor(+2.7) = " << std::floor(+2.7) << '\n'
<< "floor(-2.7) = " << std::floor(-2.7) << '\n'
<< "floor(-0.0) = " << std::floor(-0.0) << '\n'
<< "floor(-Inf) = " << std::floor(-INFINITY) << '\n';
}
//输出:
floor(+2.7) = 2.000000
floor(-2.7) = -3.000000
floor(-0.0) = -0.000000
floor(-Inf) = -inf
基础定义:计算绝对值不大于 arg 的最接近整数。
#include <cmath>
#include <iostream>
int main()
{
std::cout << std::fixed
<< "trunc(+2.7) = " << std::trunc(+2.7) << '\n'
<< "trunc(-2.9) = " << std::trunc(-2.9) << '\n'
<< "trunc(-0.0) = " << std::trunc(-0.0) << '\n'
<< "trunc(-Inf) = " << std::trunc(-INFINITY) << '\n';
}
// 可能的输出:
trunc(+2.7) = 2.000000
trunc(-2.9) = -2.000000
trunc(-0.0) = -0.000000
trunc(-Inf) = -inf
基础定义:计算 arg 的最接近整数值(以浮点格式),中点情况舍入为远离零,无关乎当前舍入模式。 计算 arg 的最接近整数值(以整数格式),中点情况舍入为远离零,无关乎当前舍入模式。
#include <iostream>
#include <cmath>
#include <cfenv>
#include <climits>
#pragma STDC FENV_ACCESS ON
int main()
{
// round
std::cout << "round(+2.3) = " << std::round(2.3)
<< " round(+2.5) = " << std::round(2.5)
<< " round(+2.7) = " << std::round(2.7) << '\n'
<< "round(-2.3) = " << std::round(-2.3)
<< " round(-2.5) = " << std::round(-2.5)
<< " round(-2.7) = " << std::round(-2.7) << '\n';
std::cout << "round(-0.0) = " << std::round(-0.0) << '\n'
<< "round(-Inf) = " << std::round(-INFINITY) << '\n';
// lround
std::cout << "lround(+2.3) = " << std::lround(2.3)
<< " lround(+2.5) = " << std::lround(2.5)
<< " lround(+2.7) = " << std::lround(2.7) << '\n'
<< "lround(-2.3) = " << std::lround(-2.3)
<< " lround(-2.5) = " << std::lround(-2.5)
<< " lround(-2.7) = " << std::lround(-2.7) << '\n';
std::cout << "lround(-0.0) = " << std::lround(-0.0) << '\n'
<< "lround(-Inf) = " << std::lround(-INFINITY) << '\n';
// 错误处理
std::feclearexcept(FE_ALL_EXCEPT);
std::cout << "std::lround(LONG_MAX+1.5) = "
<< std::lround(LONG_MAX+1.5) << '\n';
if (std::fetestexcept(FE_INVALID))
std::cout << " FE_INVALID was raised\n";
}
//可能的输出:
round(+2.3) = 2 round(+2.5) = 3 round(+2.7) = 3
round(-2.3) = -2 round(-2.5) = -3 round(-2.7) = -3
round(-0.0) = -0
round(-Inf) = -inf
lround(+2.3) = 2 lround(+2.5) = 3 lround(+2.7) = 3
lround(-2.3) = -2 lround(-2.5) = -3 lround(-2.7) = -3
lround(-0.0) = 0
lround(-Inf) = -9223372036854775808
std::lround(LONG_MAX+1.5) = -9223372036854775808
FE_INVALID was raised
若结果有别则有异常