Skip to content

第2章 数学库函数 ​


🎯 本章学习目标 ​

通过本章的学习,你将能够:

  1. 掌握三角函数:熟练使用 sin/cos/tan,牢记参数是弧度制
  2. 掌握对数函数:区分 log、log10、log2 的底数不同
  3. 掌握指数函数:理解 exp 和 pow 的区别,会用 sqrt 开平方
  4. 掌握绝对值与取整:熟练使用 abs/fabs、ceil/floor
  5. 理解浮点数精度:知道浮点数比较的陷阱,掌握 eps 比较法
  6. 了解M_PI常量:知道 π 的表示方法和注意事项
  7. 熟悉cmath头文件:知道常用数学函数的头文件
  8. 区分返回值类型:清楚各函数返回 double 类型
  9. 角度弧度转换:能进行角度和弧度的相互转换
  10. 应对真题题型:能解决选择、判断、计算等各类数学函数题目

🗺️ 本章知识图谱 ​

数学库函数
├── 头文件:<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)反正切doubledouble(弧度)返回 [-π/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)10log10(100)2.0
log2(x)log₂(x)2log2(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)平方根√xdouble

🔥 最高频易错点: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>intint整数绝对值
fabs(x)<cmath>doubledouble浮点数绝对值

⚠️ 注意:在 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 ​

类型字节数有效数字取值范围
float4约 6-7 位±3.4×10³⁸
double8约 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)√xdouble→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.071
  • log2(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                  │
└─────────────────────────────────────────────┘

百炼成钢,融会贯通