C 语言 math.h
更新时间:2026-08-26。本文是
languages/c/主题入门层第 66 篇。算平方根用sqrt、求幂用pow、取绝对值用fabs——数学函数是 C 标准库里最"即用即走"的部分。但新手第一次用sqrt就翻车:链接报错 undefined reference,因为忘了-lm。这篇把常用函数和它的脾气都讲清楚。
本文要回答的问题
- math.h 里常用的函数有哪些?
- 为什么编译要加
-lm? - 数学计算有什么精度陷阱?
一、常用函数速查
| 函数 | 作用 | 示例 |
|---|---|---|
sqrt(x) | 平方根 | sqrt(16.0) → 4.0 |
pow(x, y) | x 的 y 次方 | pow(2.0, 10) → 1024.0 |
fabs(x) | 浮点绝对值 | fabs(-3.5) → 3.5 |
floor(x) | 向下取整 | floor(3.7) → 3.0 |
ceil(x) | 向上取整 | ceil(3.2) → 4.0 |
round(x) | 四舍五入 | round(3.5) → 4.0 |
fmod(a, b) | 浮点取余 | fmod(7.5, 2.0) → 1.5 |
log(x) / log10(x) | 自然对数 / 常用对数 | log(exp(1)) → 1.0 |
sin/cos/tan | 三角函数(弧度) | sin(0.0) → 0.0 |
exp(x) | e 的 x 次方 | exp(1.0) → e |
c
#include <math.h>
#include <stdio.h>
int main(void) {
printf("%.1f\n", sqrt(16.0)); // 4.0
printf("%.1f\n", pow(2, 10)); // 1024.0
printf("%.1f\n", ceil(3.2)); // 4.0
return 0;
}二、编译必须加 -lm
c
// 不写 -lm:链接错误
// gcc math.c -o app
// undefined reference to `sqrt'
// 正确:链接数学库
gcc math.c -o app -lm为什么:math.h 只是头文件(声明),实现放在独立的 libm 库里——链接阶段要显式告诉编译器带上它。这是新手第一个"头文件对了还是报错"的经典案例。
三、整数除法:C 里 1/2 是 0
c
int a = 1, b = 2;
double r = a / b; // 0.0!不是 0.5a / b 两个整数相除,结果是整数除法(截断),赋值给 double 也救不回来。修法:
c
double r = (double)a / b; // 先把一个操作数转浮点这是数学计算最常见 bug 之一——统计、求平均、算百分比全踩过。
四、浮点精度陷阱
浮点数是近似值,比较和取整要小心:
c
printf("%d\n", (int)(0.1 * 10)); // 1?——浮点上 0.1*10 可能是 1.0000000002 或 0.9999999c
// 浮点取整配合 EPS 比较
if (fabs(a - b) < 1e-9) { // 不要 a == b
/* 视为相等 */
}要点:浮点相等用 fabs(a-b) < eps 判断;sqrt 开不尽的数(sqrt(2))是无理数近似,别拿 == 比。
五、常见坑对照
| 坑 | 现象 | 对策 |
|---|---|---|
| 忘 -lm | undefined reference | 链接加 -lm |
| 整数相除 | 结果截断为 0 | 先转 double |
| 用 == 比浮点 | 该相等不相等 | fabs 差值 < eps |
| 三角函数用角度 | 结果离谱 | sin 参数是弧度 |
| 忘 #include <math.h> | 隐式声明警告 | 头文件带上 |
六、与本站主线衔接
- 数值算法与精度深入,见浮点数原理;
- 随机数与模拟(配合 rand),见rand 与 srand;
- 命令行计算器实践用上这些函数,见命令行计算器。
一句话总结
math.h 提供 sqrt/pow/fabs/floor/ceil/round 等常用数学函数,编译要加 -lm 链接 libm;整数相除先转 double、浮点比较用差值小于 eps、三角函数的参数是弧度——数学函数很好用,三个陷阱记牢就能安稳落地。