跳到主要内容

6. math.h — 数学函数

提供数学函数。分组标注头文件: <math.h>。

浮点精度说明:常见数学函数(如 sin、cos、tan、exp、log 等)的计算结果精度为 6 位小数。如需更高精度,请使用硬件浮点单元或专用数学库。

ilogb 的边界宏:FP_ILOGB0 = -INT_MAX、FP_ILOGBNAN = INT_MAX。


6.1 三角函数 (double / float / long double)​

sin(x) / sinf(x) / sinl(x)

正弦。

  • 输入: x 弧度
  • 输出: 正弦值

cos(x) / cosf(x) / cosl(x)

余弦。

  • 输入: x 弧度
  • 输出: 余弦值

tan(x) / tanf(x) / tanl(x)

正切。

  • 输入: x 弧度
  • 输出: 正切值
  • 注意: x 接近 π/2+kπ 时结果趋于无穷

asin(x) / asinf(x) / asinl(x)

反正弦。

  • 输入: x [-1,1]
  • 输出: [-π/2, π/2]

acos(x) / acosf(x) / acosl(x)

反余弦。

  • 输入: x [-1,1]
  • 输出: [0, π]

atan(x) / atanf(x) / atanl(x)

反正切。

  • 输入: x 实数
  • 输出: (-π/2, π/2)

atan2(y, x) / atan2f(y, x) / atan2l(y, x)

四象限反正切。

  • 输入: y y坐标, x x坐标
  • 输出: [-π, π]
  • 注意: 可正确处理 x=0 的情况

6.2 双曲函数​

sinh(x) / sinhf(x) / sinhl(x)

双曲正弦。

  • 输入: x 实数
  • 输出: 双曲正弦值

cosh(x) / coshf(x) / coshl(x)

双曲余弦。

  • 输入: x 实数
  • 输出: 双曲余弦值
  • 注意: 结果始终 >= 1

tanh(x) / tanhf(x) / tanhl(x)

双曲正切。

  • 输入: x 实数
  • 输出: (-1, 1)

asinh(x) / asinhf(x) / asinhl(x)

反双曲正弦。

  • 输入: x 实数
  • 输出: 反双曲正弦值

acosh(x) / acoshf(x) / acoshl(x)

反双曲余弦。

  • 输入: x [1,+∞)
  • 输出: [0,+∞)
  • 注意: x < 1 时返回 NaN

atanh(x) / atanhf(x) / atanhl(x)

反双曲正切。

  • 输入: x (-1,1)
  • 输出: 实数
  • 注意: |x| >= 1 时返回 NaN

6.3 指数与对数​

exp(x) / expf(x) / expl(x)

e^x。

  • 输入: x 实数
  • 输出: e^x

exp2(x) / exp2f(x) / exp2l(x)

2^x。

  • 输入: x 实数
  • 输出: 2^x

expm1(x) / expm1f(x) / expm1l(x)

e^x - 1。

  • 输入: x 实数
  • 输出: e^x - 1
  • 注意: x 接近 0 时比 exp(x)-1 更精确

log(x) / logf(x) / logl(x)

自然对数。

  • 输入: x > 0
  • 输出: ln(x)
  • 注意: x <= 0 时返回 NaN/无穷

log10(x) / log10f(x) / log10l(x)

常用对数。

  • 输入: x > 0
  • 输出: log10(x)

log2(x) / log2f(x) / log2l(x)

二进制对数。

  • 输入: x > 0
  • 输出: log2(x)

log1p(x) / log1pf(x) / log1pl(x)

ln(1+x)

  • 输入: x > -1
  • 输出: ln(1+x)
  • 注意: x 接近 0 时比 log(1+x) 更精确

logb(x) / logbf(x) / logbl(x)

提取指数。

  • 输入: x != 0
  • 输出: 浮点指数(浮点数)
  • 注意: 返回值为 double/float/long double

ilogb(x) / ilogbf(x) / ilogbl(x)

提取指数为整数。

  • 输入: x != 0
  • 输出: int 指数
  • 注意: 返回 FP_ILOGB0(0)/FP_ILOGBNAN(NaN)

6.4 幂运算​

pow(x, y) / powf(x, y) / powl(x, y)

x^y。

  • 输入: x 底数, y 指数
  • 输出: 幂值
  • 注意: 0^0 返回 1

sqrt(x) / sqrtf(x) / sqrtl(x)

平方根。

  • 输入: x >= 0
  • 输出: 平方根
  • 注意: x < 0 时返回 NaN

cbrt(x) / cbrtf(x) / cbrtl(x)

立方根。

  • 输入: x 实数
  • 输出: 立方根
  • 注意: 可接受负数

hypot(x, y) / hypotf(x, y) / hypotl(x, y)

sqrt(x^2+y^2)

  • 输入: x、y 两直角边
  • 输出: 斜边长
  • 注意: 防溢出/下溢的中间处理

6.5 取整与余数​

ceil(x) / ceilf(x) / ceill(x)

向上取整。

  • 输入: x 实数
  • 输出: >= x 的最小整数

floor(x) / floorf(x) / floorl(x)

向下取整。

  • 输入: x 实数
  • 输出: <= x 的最大整数

round(x) / roundf(x) / roundl(x)

四舍五入(远离零)

  • 输入: x 实数
  • 输出: 最接近的整数,0.5 远离零

trunc(x) / truncf(x) / truncl(x)

向零取整。

  • 输入: x 实数
  • 输出: 截断小数部分

rint(x) / rintf(x) / rintl(x)

就近取整(使用当前舍入模式)

  • 输入: x 实数
  • 输出: 最接近的整数
  • 注意: 可能引发不精确异常

lrint(x) / lrintf(x) / lrintl(x)

就近取整为 long。

  • 输入: x 实数
  • 输出: long

llrint(x) / llrintf(x) / llrintl(x)

就近取整为 long long。

  • 输入: x 实数
  • 输出: long long

lround(x) / lroundf(x) / lroundl(x)

四舍五入为 long。

  • 输入: x 实数
  • 输出: long

llround(x) / llroundf(x) / llroundl(x)

四舍五入为 long long。

  • 输入: x 实数
  • 输出: long long

fmod(x, y) / fmodf(x, y) / fmodl(x, y)

浮点取模。

  • 输入: x 被除数, y 除数
  • 输出: x - trunc(x/y) * y
  • 注意: 结果与 x 同号

remainder(x, y) / remainderf(x, y) / remainderl(x, y)

IEEE 余数。

  • 输入: x 被除数, y 除数
  • 输出: x - round(x/y) * y
  • 注意: 结果范围 [-y/2, y/2]

remquo(x, y, quo) / remquof(x, y, quo) / remquol(x, y, quo)

余数与商。

  • 输入: x 被除数, y 除数, quo 商指针
  • 输出: double/float/long double 余数
  • 注意: quo 返回商的低几位(至少 3 位)

modf(x, iptr) / modff(x, iptr) / modfl(x, iptr)

分解为整数和小数部分。

  • 输入: x 实数, iptr 整数部分指针
  • 输出: 小数部分
  • 注意: 两部分均与 x 同号

frexp(x, exp) / frexpf(x, exp) / frexpl(x, exp)

分解为尾数和指数。

  • 输入: x 实数, exp 指数指针(输出)
  • 输出: double/float/long double 尾数 [0.5, 1)
  • 注意: x = 尾数 * 2^exp

ldexp(x, exp)

x * 2^exp。

  • 输入: x 尾数, exp 整数指数
  • 输出: x * 2^exp

scalbn(x, n) / scalbnf(x, n) / scalbnl(x, n)

x * FLT_RADIX^n。

  • 输入: x 实数, n 整数指数
  • 输出: x * FLT_RADIX^n
  • 注意: FLT_RADIX 通常为 2

scalbln(x, n) / scalblnf(x, n) / scalblnl(x, n)

x * FLT_RADIX^n。

  • 输入: x 实数, n long 指数
  • 输出: x * FLT_RADIX^n

nearbyint(x) / nearbyintf(x) / nearbyintl(x)

就近取整(不引发异常)

  • 输入: x 实数
  • 输出: 最接近的整数
  • 注意: kf32 不支持(软浮点 NOEXCEPT 下退化为 rint,不保证不引发异常)

6.6 特殊函数​

erf(x) / erff(x) / erfl(x)

误差函数。

  • 输入: x 实数
  • 输出: 误差函数值

erfc(x) / erfcf(x) / erfcl(x)

互补误差函数。

  • 输入: x 实数
  • 输出: 1 - erf(x)
  • 注意: x 较大时比 1-erf(x) 更精确

tgamma(x) / tgammaf(x) / tgammal(x)

伽马函数 Γ(x)

  • 输入: x 实数
  • 输出: Γ(x)
  • 注意: x 为负整数或 0 时返回无穷/Nan

lgamma(x) / lgammaf(x) / lgammal(x)

ln|Γ(x)|。

  • 输入: x 实数
  • 输出: ln|Γ(x)|
  • 注意: 设置全局变量 signgam 表示 Γ(x) 的符号

6.7 绝对值与最值​

fabs(x) / fabsf(x) / fabsl(x)

绝对值。

  • 输入: x 实数
  • 输出: |x|

fdim(x, y) / fdimf(x, y) / fdiml(x, y)

max(x-y, 0)

  • 输入: x、y 实数
  • 输出: x-y(正)或 0

fmax(x, y) / fmaxf(x, y) / fmaxl(x, y)

最大值。

  • 输入: x、y 实数
  • 输出: 较大值
  • 注意: 一个为 NaN 时返回另一个

fmin(x, y) / fminf(x, y) / fminl(x, y)

最小值。

  • 输入: x、y 实数
  • 输出: 较小值
  • 注意: 一个为 NaN 时返回另一个

copysign(x, y) / copysignf(x, y) / copysignl(x, y)

复制符号。

  • 输入: x 数值, y 符号来源
  • 输出: x 的绝对值配上 y 的符号

signbit(x) / signbitf(x) / signbitl(x)

检查符号位。

  • 输入: x 实数
  • 输出: int 非零表示负数
  • 注意: -0 返回非零,NaN 符号依赖于实现

6.8 浮点分类与操作​

isfinite(x) / isfinitef(x) / finitel(x)

是否为有限数。

  • 输入: x 实数
  • 输出: int 非零表示有限

isinf(x) / isinff(x) / isinfl(x)

是否为无穷大。

  • 输入: x 实数
  • 输出: int 非零表示无穷

isnan(x) / isnanf(x) / isnanl(x)

是否为 NaN。

  • 输入: x 实数
  • 输出: int 非零表示 NaN

fpclassify(x) / fpclassifyf(x) / fpclassifyl(x)

浮点数分类。

  • 输入: x 实数
  • 输出: int FP_NAN/FP_INFINITE/FP_ZERO/FP_SUBNORMAL/FP_NORMAL

nan(tagp) / nanf(tagp) / nanl(tagp)

生成安静 NaN。

  • 输入: tagp 标签字符串(可为空)
  • 输出: double/float/long double 安静 NaN
  • 注意: tagp 内容编码在 NaN 载荷中

nextafter(x, y) / nextafterf(x, y) / nextafterl(x, y)

下一个可表示浮点数。

  • 输入: x 起始值, y 目标方向
  • 输出: x 之后朝 y 方向的下一个可表示值
  • 注意: x==y 时返回 y

nexttoward(x, y) / nexttowardf(x, y) / nexttowardl(x, y)

下一个可表示值。

  • 输入: x 起始值, y 目标方向(long double)
  • 输出: x 之后朝 y 方向的下一个可表示值

fma(x, y, z) / fmaf(x, y, z) / fmal(x, y, z)

融合乘加 (x*y)+z。

  • 输入: x、y、z 实数
  • 输出: (x*y)+z
  • 注意: 只做一次舍入,比 (x*y)+z 更精确;在部分平台上可能因内部扩展精度导致结果与预期不符,存在精度丢失风险

int isnormal(real-floating x) | 【C99 §7.12.3.5】

判断是否为正规数(非 0、非 subnormal、非 inf、非 NaN)。

  • 输入: x 浮点数
  • 输出: int 非零表示正规数
  • 注意: 宏,等价于 __builtin_isnormal 或 fpclassify(x) == FP_NORMAL。

6.9 比较宏​

isgreater(x, y)

x > y(不引发无效异常)

  • 输入: x、y 实数
  • 输出: int 非零表示 x > y
  • 注意: x 或 y 为 NaN 时返回 0,不引发异常

isgreaterequal(x, y)

x >= y。

  • 输入: x、y 实数
  • 输出: int 非零表示 x >= y

isless(x, y)

x < y。

  • 输入: x、y 实数
  • 输出: int 非零表示 x < y

islessequal(x, y)

x <= y。

  • 输入: x、y 实数
  • 输出: int 非零表示 x <= y

islessgreater(x, y)

x <> y(有序)

  • 输入: x、y 实数
  • 输出: int 非零表示有序且不相等

isunordered(x, y)

是否无序比较。

  • 输入: x、y 实数
  • 输出: int 非零表示至少一个是 NaN