Appearance
第2章 数学库函数
🎯 本章学习目标
通过本章的学习,你将能够:
- 掌握三角函数:熟练使用 sin/cos/tan,牢记参数是弧度制
- 掌握对数函数:区分 log、log10、log2 的底数不同
- 掌握指数函数:理解 exp 和 pow 的区别,会用 sqrt 开平方
- 掌握绝对值与取整:熟练使用 abs/fabs、ceil/floor
- 理解浮点数精度:知道浮点数比较的陷阱,掌握 eps 比较法
- 了解M_PI常量:知道 π 的表示方法和注意事项
- 熟悉cmath头文件:知道常用数学函数的头文件
- 区分返回值类型:清楚各函数返回 double 类型
- 角度弧度转换:能进行角度和弧度的相互转换
- 应对真题题型:能解决选择、判断、计算等各类数学函数题目
🗺️ 本章知识图谱
数学库函数
├── 头文件:<cmath>
├── 三角函数
│ ├── sin(x) 正弦
│ ├── cos(x) 余弦
│ ├── tan(x) 正切
│ └── ⚠️ 参数是弧度制
│ └── 弧度 = 角度 × π / 180
├── 对数函数
│ ├── log(x) 自然对数(底e)
│ ├── log10(x) 以10为底
│ ├── log2(x) 以2为底
│ └── ⚠️ 参数必须 > 0
├── 指数函数
│ ├── exp(x) = e^x
│ ├── pow(a, b) = a^b
│ │ └── 返回 double
│ └── sqrt(x) 开平方
│ └── 参数 >= 0
├── 绝对值函数
│ ├── abs(x) 整数绝对值
│ └── fabs(x) 浮点数绝对值
├── 取整函数
│ ├── ceil(x) 向上取整(天花板)
│ ├── floor(x) 向下取整(地板)
│ └── round(x) 四舍五入(了解)
├── 常量
│ ├── M_PI = π(可能需要#define _USE_MATH_DEFINES)
│ └── M_E = e
├── 浮点数精度
│ ├── 不能直接用 == 比较
│ ├── 用 fabs(a-b) < eps
│ └── eps = 1e-8 左右
└── 易错点汇总
├── 三角函数用弧度
├── log()是自然对数
├── pow()返回double
└── 浮点数比较用eps一、📌 考纲原文
(1)掌握数学库常用函数(三角、对数、指数),三角函数包括
sin(x),cos(x)等;对数函数包括log10(x):返回 x 以 10 为底的对数,log2(x):返回 x 以 2 为底的对数;指数函数包括exp(x):计算指数函数,返回 x 的以 e 为底的指数函数。
看起来简单?但真题告诉你:这个模块的坑,比你想的多得多。
二、万事开头:头文件 <cmath>
所有数学库函数都在 <cmath>(C++风格)或 <math.h>(C风格)中,使用前必须引入:
cpp
#include <cmath> // 推荐
// 或者万能头文件
#include <bits/stdc++.h> // 比赛常用,包含一切⚠️ 黄金法则:
<cmath>中的函数参数和返回值通常都是double类型(浮点数)。这是整个模块最核心的考点之一,反复出现在判断题中。
三、三角函数:弧度制,不是角度制!
函数一览表
| 函数 | 功能 | 参数类型 | 返回值类型 | 备注 |
|---|---|---|---|---|
sin(x) | 正弦 | double(弧度) | double | |
cos(x) | 余弦 | double(弧度) | double | |
tan(x) | 正切 | double(弧度) | double | |
asin(x) | 反正弦 | double(值域[-1,1]) | double(弧度) | 返回 [-π/2, π/2] |
acos(x) | 反余弦 | double(值域[-1,1]) | double(弧度) | 返回 [0, π] |
atan(x) | 反正切 | double | double(弧度) | 返回 [-π/2, π/2] |
🔥 最高频易错点:弧度 vs 角度
C++ 的三角函数参数一律是弧度(radian),不是角度(degree)!
sin(90) ≠ 1 // 90 是弧度,约等于 5157°,sin(90弧度) ≈ 0.894
sin(π/2) = 1 // π/2 弧度 = 90°,这才是正确的角度转弧度公式:
弧度 = 角度 × π / 180
角度 = 弧度 × 180 / π代码示例
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
// 获取 π 的高精度值(推荐方式)
double pi = acos(-1.0); // acos(-1) = π
// ❌ 错误:直接传角度
cout << sin(90) << endl; // 输出 0.893997...(不是 1!)
// ✅ 正确:角度转弧度
double angle = 90.0;
double radian = angle * pi / 180.0;
cout << sin(radian) << endl; // 输出 1
// 常见角度值
cout << sin(30 * pi / 180) << endl; // sin(30°) = 0.5
cout << cos(60 * pi / 180) << endl; // cos(60°) = 0.5
cout << tan(45 * pi / 180) << endl; // tan(45°) ≈ 1.0
return 0;
}📝 考试怎么考
- 判断题:「三角函数默认使用角度制」→ ❌ 错误(2026年6月真题判断第1题)
- 选择题:「
sin(90)的参数 90 表示 90 度」→ ❌ 错误(2026年6月真题选择第2题选项D) - 选择题:
sin(3.1415926 / 2)的输出是?→ 1(2024年6月真题选择第1题,因为 π/2 弧度 = 90°)
四、对数函数:三个 log,别搞混!
函数辨析表
| 函数 | 数学含义 | 底数 | 示例 | 结果 |
|---|---|---|---|---|
log(x) | ln(x) | e(自然对数) | log(2.71828) | ≈ 1.0 |
log10(x) | lg(x) | 10 | log10(100) | 2.0 |
log2(x) | log₂(x) | 2 | log2(8) | 3.0 |
🔥 最高频易错点:log(x) 不是 log₁₀(x)!
很多同学看到 log 就以为是以 10 为底,大错特错!C++ 中的 log(x) 是自然对数 ln(x),以 e 为底。
log(100) ≈ 4.605 // 这是 ln(100),不是 2!
log10(100) = 2 // 这才是以 10 为底换底公式:如果需要计算以任意底数 a 的对数 logₐ(b):
cpp
double result = log(b) / log(a); // 换底公式代码示例
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
cout << log10(100) << endl; // 2(以10为底)
cout << log10(1000) << endl; // 3
cout << log2(8) << endl; // 3(以2为底)
cout << log2(1024) << endl; // 10
cout << log(exp(1.0)) << endl; // 1(ln(e) = 1)
// ⚠️ 注意:log(8) 不是 3!
cout << log(8) << endl; // ≈ 2.079(这是 ln(8))
return 0;
}📝 考试怎么考
- 判断题:「
log(128)的结果类型为 double、值约为 7.0」→ ❌ 错误(2025年9月真题判断第5题,log(128) = ln(128) ≈ 4.85,不是 7.0。7.0 是 log₂(128) 的值) - 选择题:「
log(8)的值是多少?」→ ln(8) ≈ 2.079,不是 3(2023年12月真题第11题) - 选择题:「
log2(32)的返回值类型为 int」→ ❌ 错误,返回值是 double(2026年6月真题选择第2题选项B)
五、指数函数:exp / pow / sqrt
函数一览表
| 函数 | 功能 | 数学公式 | 返回值类型 |
|---|---|---|---|
exp(x) | e 的 x 次方 | eˣ | double |
pow(x, y) | x 的 y 次方 | xʸ | double |
sqrt(x) | 平方根 | √x | double |
🔥 最高频易错点:pow() 返回值是 double,不是 int!
即使你写 pow(2, 10),两个参数都是 int,返回值仍然是 double(1024.0),不是 int!
cpp
// pow(2, 10) 的返回值是 double 类型的 1024.0
// 不是 int 类型的 1024代码示例
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
// exp(x): e 的 x 次方
cout << exp(1.0) << endl; // ≈ 2.71828(e 的值)
cout << exp(0) << endl; // 1(e⁰ = 1)
// pow(x, y): x 的 y 次方
cout << pow(2, 10) << endl; // 1024
cout << pow(3, 3) << endl; // 27
cout << pow(2.5, 2) << endl; // 6.25
// sqrt(x): 平方根
cout << sqrt(16) << endl; // 4
cout << sqrt(2) << endl; // ≈ 1.41421
// 实际应用:勾股定理求斜边
double a = 3.0, b = 4.0;
double c = sqrt(pow(a, 2) + pow(b, 2));
cout << c << endl; // 5
return 0;
}📝 考试怎么考
- 判断题:「
pow(2, 10)由于参数均为整型 int,返回值类型也为整型 int」→ ❌ 错误(2026年6月真题判断第2题) - 判断题:「
pow(10, 3)的结果的值为 1000、类型为 int」→ ❌ 错误(2025年9月真题判断第5题,值正确但类型是 double) - 选择题:「
pow(2, 5)的返回值类型一定为 int」→ ❌ 错误(2026年6月真题选择第2题选项C)
六、绝对值与取整函数
绝对值函数辨析
| 函数 | 头文件 | 参数类型 | 返回值类型 | 适用场景 |
|---|---|---|---|---|
abs(x) | <cstdlib> / <cmath> | int | int | 整数绝对值 |
fabs(x) | <cmath> | double | double | 浮点数绝对值 |
⚠️ 注意:在 C++ 中,
abs()对整数返回int,fabs()对浮点数返回double。如果对浮点数使用abs(),在不同编译器下行为可能不同,浮点数推荐使用fabs()。
cpp
cout << abs(-5) << endl; // 5(整数)
cout << fabs(-3.14) << endl; // 3.14(浮点数)取整函数辨析
| 函数 | 功能 | 示例 | 结果 |
|---|---|---|---|
floor(x) | 向下取整(地板) | floor(3.7) | 3.0 |
ceil(x) | 向上取整(天花板) | ceil(3.2) | 4.0 |
round(x) | 四舍五入 | round(3.5) | 4.0 |
记忆口诀:floor 向下踩地板,ceil 向上碰天花板,round 就是你小学学的四舍五入。
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
cout << floor(3.7) << endl; // 3
cout << floor(-3.2) << endl; // -4(注意负数向下取整!)
cout << ceil(3.2) << endl; // 4
cout << ceil(-3.7) << endl; // -3(负数向上取整!)
cout << round(3.4) << endl; // 3
cout << round(3.5) << endl; // 4
cout << round(2.5) << endl; // 3(四舍五入,.5 进位)
return 0;
}💡 考试技巧:负数的取整方向最容易出题!
floor(-3.2) = -4,ceil(-3.2) = -3,别凭直觉选反了。
七、常量 M_PI:好用但不一定有
M_PI 是 π 的宏定义常量(≈ 3.14159265358979...),在部分编译器中通过 <cmath> 即可使用。
但问题在于:M_PI 不是 C++ 标准的一部分,在某些编译器(如 MSVC)中默认不可用。需要手动定义或使用其他方式获取。
推荐获取 π 的方式
cpp
// 方式一:acos(-1.0) —— 最安全,所有编译器都支持
double pi = acos(-1.0);
// 方式二:手动定义(推荐在比赛开头写上)
const double PI = 3.14159265358979323846;
// 方式三:M_PI(需要确认编译器支持)
// 部分编译器需要 #define _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#include <cmath>
// 然后可以使用 M_PI🏆 考试建议:直接用
acos(-1.0)最稳妥,不依赖任何宏定义,万无一失。
八、精度问题:浮点数的"暗坑"
double vs float
| 类型 | 字节数 | 有效数字 | 取值范围 |
|---|---|---|---|
float | 4 | 约 6-7 位 | ±3.4×10³⁸ |
double | 8 | 约 15-16 位 | ±1.7×10³⁰⁸ |
结论:竞赛和考试中,几乎总是使用 double,除非题目对内存有极端限制。
🔥 浮点数比较的陷阱
由于浮点数在计算机中以二进制存储,存在精度误差,不能直接用 == 比较两个浮点数!
cpp
// ❌ 危险!可能不相等
if (sqrt(2) * sqrt(2) == 2.0) { ... }
// ✅ 正确!使用误差范围(epsilon)
const double EPS = 1e-9;
if (fabs(sqrt(2) * sqrt(2) - 2.0) < EPS) {
cout << "相等" << endl;
}典型精度陷阱示例
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
// 陷阱1:pow 的精度问题
cout << (int)pow(10, 3) << endl; // 大多数编译器输出 1000
// 但有些编译器可能输出 999!因为 pow(10,3) 可能是 999.9999...
// 避坑写法:加上一个极小值再强转,或者使用 round
int result = (int)(pow(10, 3) + 0.5); // 推荐用于非负数取整
// 或者
result = round(pow(10, 3)); // 最稳妥
// 陷阱2:浮点运算的累积误差
double sum = 0.0;
for (int i = 0; i < 10; i++) {
sum += 0.1;
}
cout << sum << endl; // 可能不是精确的 1.0
// 陷阱3:sqrt 和 log2 组合计算
// 2026年6月真题第1题:
cout << (int)(sqrt(50) + log2(8)) << endl;
// sqrt(50) ≈ 7.071, log2(8) = 3.0
// 7.071 + 3.0 = 10.071, (int)10.071 = 10
// 答案:10
return 0;
}⚠️ 考试技巧:当题目用
(int)强转浮点数时,注意直接截断小数部分(不是四舍五入)。比如(int)10.99 = 10,不是 11。
九、数学库函数速查总表
| 分类 | 函数 | 功能 | 参数→返回 | 高频考点 |
|---|---|---|---|---|
| 三角 | sin/cos/tan(x) | 三角函数 | double→double | 弧度制 |
| 反三角 | asin/acos/atan(x) | 反三角函数 | double→double | 返回弧度 |
| 对数 | log(x) | 自然对数 ln(x) | double→double | 底数是 e,不是 10 |
| 对数 | log10(x) | 以 10 为底 | double→double | 考纲重点 |
| 对数 | log2(x) | 以 2 为底 | double→double | 考纲重点 |
| 指数 | exp(x) | eˣ | double→double | 考纲重点 |
| 幂 | pow(x, y) | xʸ | double→double | 返回 double |
| 开方 | sqrt(x) | √x | double→double | 返回 double |
| 绝对值 | abs(x) | 整数绝对值 | int→int | 与 fabs 区分 |
| 绝对值 | fabs(x) | 浮点绝对值 | double→double | 浮点数用这个 |
| 取整 | floor(x) | 向下取整 | double→double | 负数方向 |
| 取整 | ceil(x) | 向上取整 | double→double | 负数方向 |
| 取整 | round(x) | 四舍五入 | double→double | .5 进位 |
十、📝 实战练习
练习题 1(单选题)
题目: 下列 C++ 代码的输出结果是( )。
cpp
#include <iostream>
#include <cmath>
using namespace std;
int main() {
cout << (int)(sqrt(50) + log2(8));
return 0;
}A. 9 B. 10 C. 11 D. 12
🔑 点击查看答案与解析
答案: B
解析:
sqrt(50)≈ 7.071log2(8)= 3.0(2³ = 8)- 7.071 + 3.0 = 10.071
(int)10.071= 10(直接截断小数部分,不是四舍五入)
本题为 2026 年 6 月 GESP 七级真题第 1 题。
练习题 2(单选题)
题目: 下列关于 <cmath> 中数学库函数的说法,正确的是( )。
A. log2(32) 的返回值类型为 int
B. pow(2, 5) 的返回值类型一定为 int
C. sqrt(49) 的返回值可以参与浮点运算
D. sin(90) 的参数 90 表示 90 度
🔑 点击查看答案与解析
答案: C
解析:
- A 错误:
log2(32)返回double类型(5.0),不是int - B 错误:
pow(2, 5)返回double类型(32.0),不是int。即使参数都是 int,返回值也是 double - C 正确:
sqrt(49)返回double类型的 7.0,完全可以参与浮点运算 - D 错误:
sin(90)中的 90 是弧度,不是角度。90 弧度 ≈ 5157°
本题为 2026 年 6 月 GESP 七级真题第 2 题。
练习题 3(判断题)
题目: 使用 <cmath> 或 <math.h> 头文件中的函数,表达式 log(256) 的结果类型为 double、值约为 8.0。
🔑 点击查看答案与解析
答案: 错误 ❌
解析:
log(256)是自然对数 ln(256),以 e 为底,不是以 2 为底- ln(256) ≈ 5.545,不是 8.0
- 8.0 是
log2(256)的值(2⁸ = 256) - 返回值类型确实是
double,但值不是 8.0 - 这道题的陷阱就在于
log≠log2!
类似题目出现在 2025 年 9 月 GESP 七级判断题中。
练习题 4(单选题)
题目: C++ 中 log10(1000) 的返回值是多少?( )
A. 2
B. 3
C. 6.9
D. 1000
🔑 点击查看答案与解析
答案: B
解析:log10(x) 是以 10 为底的对数函数。
log10(1000) = log₁₀(10³) = 3
选 B。
💡 记忆:log10(100) = 2,log10(1000) = 3,log10(1) = 0。以 10 为底,就是问"10 的几次方等于 x"。
练习题 5(单选题)
题目: ceil(-2.3) 和 floor(-2.3) 的结果分别是?( )
A. -2 和 -3
B. -3 和 -2
C. -2 和 -2
D. -3 和 -3
🔑 点击查看答案与解析
答案: A
解析:
- ceil:向上取整(向正无穷方向)→ ceil(-2.3) = -2(-2 比 -2.3 大)
- floor:向下取整(向负无穷方向)→ floor(-2.3) = -3(-3 比 -2.3 小)
正数的情况好记:ceil(2.3) = 3, floor(2.3) = 2 负数容易搞混,记住:
- ceil = 天花板 → 往高处走(变大)
- floor = 地板 → 往低处走(变小)
选 A。
🍎 生活比喻:你在-2.3楼(地下2.3层),ceil是往楼上走(到-2楼),floor是往楼下走(到-3楼)。
练习题 6(判断题)
题目: 在 C++ 中,可以直接用 == 比较两个 double 类型的变量是否相等。( )
🔑 点击查看答案与解析
答案: 错误 ❌
解析: 浮点数在计算机中存储有精度误差,不能直接用 == 比较。
正确做法:判断两个数的差的绝对值小于一个很小的数(eps):
cpp
if (fabs(a - b) < 1e-8) { // 认为相等
// ...
}🔥 高频考点:浮点数比较是判断题的常客。记住:double 不能直接 == 比较。
练习题 7(单选题)
题目: sqrt(16) 的返回值类型和值分别是?( )
A. int 类型,值为 4
B. double 类型,值为 4.0
C. int 类型,值为 4.0
D. float 类型,值为 4.0
🔑 点击查看答案与解析
答案: B
解析:sqrt() 函数的返回值类型是 double,不是 int。
即使结果是整数(如 sqrt(16) = 4),返回的也是 double 类型的 4.0。
同样,pow() 也返回 double。
选 B。
💡 记住:
<cmath>里的函数几乎都返回 double 类型。如果需要 int,要自己强制类型转换。
练习题 8(单选题)
题目: exp(1) 的值大约等于?( )
A. 1
B. 2.71828
C. 3.14159
D. 10
🔑 点击查看答案与解析
答案: B
解析:exp(x) 计算 e 的 x 次方,即 eˣ。
exp(1) = e¹ = e ≈ 2.71828
- 3.14159 是 π(M_PI)
- e ≈ 2.71828(M_E)
选 B。
💡 记忆:exp = e的幂次。exp(1) = e,exp(2) = e²,以此类推。
十一、📊 考点总结表
| 考点 | 重要程度 | 出题形式 | 易错点 |
|---|---|---|---|
| 三角函数用弧度制 | ⭐⭐⭐⭐⭐ | 判断题/选择题 | 参数是弧度不是角度 |
| log() 是自然对数 | ⭐⭐⭐⭐⭐ | 判断题/选择题 | 底是e不是10;log10才是以10为底 |
| pow() 返回 double | ⭐⭐⭐⭐⭐ | 判断题/选择题 | 不是int,不能直接当数组下标 |
| sqrt() 开平方 | ⭐⭐⭐⭐ | 选择题/编程 | 参数>=0;返回double |
| exp() = e的x次方 | ⭐⭐⭐⭐ | 选择题 | exp(1)=e≈2.718 |
| ceil/floor 取整 | ⭐⭐⭐⭐ | 选择题 | 负数容易搞反方向 |
| 浮点数比较用 eps | ⭐⭐⭐⭐ | 判断题 | 不能直接用 == |
| abs vs fabs | ⭐⭐⭐ | 选择题 | abs用于int,fabs用于double |
| M_PI 常量 | ⭐⭐⭐ | 选择题/编程 | 可能需要定义 _USE_MATH_DEFINES |
| log2(x) 以2为底 | ⭐⭐⭐ | 选择题 | 和 log(x) 区分开 |
⭐ 必背速记卡
┌─────────────────────────────────────────────┐
│ 数学库函数 · 必背速记卡 │
├─────────────────────────────────────────────┤
│ 1. 头文件:#include <cmath> │
│ 2. 三角函数参数是弧度,不是角度 │
│ 3. 弧度 = 角度 × M_PI / 180 │
│ 4. log(x) 是自然对数(底e) │
│ 5. log10(x) 以10为底,log2(x) 以2为底 │
│ 6. exp(x) = e^x,exp(1) = e ≈ 2.718 │
│ 7. pow(a,b) = a^b,返回double │
│ 8. sqrt(x) 开平方,参数>=0 │
│ 9. ceil 向上取整,floor 向下取整 │
│ 10. abs 整数绝对值,fabs 浮点绝对值 │
│ 11. 浮点数不能直接用==比较 │
│ 12. fabs(a-b) < 1e-8 认为相等 │
│ 13. M_PI = π,M_E = e │
│ 14. cmath函数大多返回double类型 │
│ 15. 三角函数:sin/cos/tan │
└─────────────────────────────────────────────┘