数学函数
<math.h> 提供了大量面向实数(主要是浮点类型)的数学函数与工具宏。它的核心使用方式是:用 double/float/long double 表示实数,再用标准库函数完成常见运算(指数、对数、三角、开方、取整等)。
注意
<math.h> 中很多函数对输入值有定义域要求。遇到“看起来算不出来”的情况时,应先检查:
- 输入是否超出定义域(如
sqrt(x)的x为负); - 结果是否溢出为无穷大(如
exp(1000)); - 是否产生 NaN(如
0.0 / 0.0)。
1. 常用宏与分类函数
1.1 特殊值:INFINITY / NAN
INFINITY 与 NAN 是两个宏,分别表示正无穷与 NaN(Not a Number)。它们通常用于:表达“不可表示的结果”、或者在计算中作为哨兵值。
1.2 浮点分类:isfinite / isinf / isnan / fpclassify
对浮点计算结果进行分类,是写健壮数学代码的常用技巧:
c
#include <math.h>
int isfinite(real-floating x);
int isinf(real-floating x);
int isnan(real-floating x);
int fpclassify(real-floating x);1
2
3
4
5
6
2
3
4
5
6
(标准里的形参类型写作 real-floating,表示“实浮点类型”;实际函数对 float/double/long double 都可用。)
fpclassify 的结果会落在若干宏之一:FP_NAN、FP_INFINITE、FP_ZERO、FP_SUBNORMAL、FP_NORMAL。
2. 常见函数类别(选读清单)
本节只列常见类别,不试图覆盖所有接口:
- 三角函数:
sin/cos/tan及其反函数asin/acos/atan(注意:大多数函数输入/输出都以“弧度”为单位) - 指数与对数:
exp/log/log10 - 幂与开方:
pow/sqrt/cbrt - 取整与舍入:
ceil/floor/trunc/round - 绝对值与余数:
fabs/fmod/remainder - 距离:
hypot(用于计算 ,比手写sqrt(x*x+y*y)更稳健)
3. 错误处理:返回值优先,其次看错误状态
多数 <math.h> 函数会通过“返回值”表达计算结果;当发生定义域错误/上溢等情况时,标准允许实现以多种方式报告错误(例如设置 errno,或者产生浮点异常)。因此工程实践中更推荐:
- 先检查返回值是否为
NaN/INFINITY; - 必要时再结合
errno或<fenv.h>(见 17.7)。
4. 示例:角度转弧度并计算正弦
c
#include <math.h>
#include <stdio.h>
int main(void) {
double deg;
if (scanf("%lf", °) != 1) {
return 1;
}
const double pi = acos(-1.0);
double rad = deg * pi / 180.0;
printf("rad = %.6f\n", rad);
printf("sin = %.6f\n", sin(rad));
return 0;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
习题
#11701
⚡2⏳2
使用 <math.h> 中的函数解决 10401。
#11702
⚡3⏳2
写一个程序:从标准输入读入两个 double,输出它们的欧氏距离
要求:
- 使用
hypot(不要直接写sqrt(x*x + y*y)); - 输入失败时退出;
- 输出保留 6 位小数。
#11703
⚡4⏳3
写一个程序:从标准输入读入一个 double,输出 sqrt(x);若 x 为负,输出一条错误信息到标准错误流并退出。
要求:
- 使用
isnan或fpclassify对结果进行检查; - 不要假设输入一定成功;
- 出错信息写到
stderr(提示:fprintf(stderr, ...))。