各位读者朋友,大家好。今天这篇想聊一个看似“高深”但其实贯穿了整个数学与工程体系的话题——泰勒展开。之所以起这个标题,是因为你仔细琢磨后会发现,泰勒展开背后的核心直觉,并不是大学高等数学课上那堆复杂的公式,而是“用简单的东西去近似复杂的东西”。这种想法小学二年级就已经在用了。
举个例子,小学生算圆的周长时,最直观的方法是把圆看成一个非常接近圆的正多边形,用多边形边长去近似圆周长;再比如估算一个数的平方根,先找一个接近它的完全平方数,再通过加减来逼近真实值。这些本质上都是“近似”的思想,而泰勒展开,就是把这种近似思想进行系统化、公式化、可控制误差的升级。
这篇文章我会尽可能用程序员友好的方式,把泰勒展开从头拆一遍:先说明它到底在做什么,为什么说它本质上并不难;然后给出核心公式、常用展开式、手算示例;再用 Python 亲手算一遍,看看展开式逼近真实函数的效果;最后聊聊它在数值计算、机器学习、游戏开发、最优化算法里出现的场景。文中会给出可以直接运行的代码和清晰的结果说明,希望能让基础薄弱的人看懂概念,也能让有开发经验的读者快速上手。
1. 泰勒展开到底在做什么?为什么说它“小学二年级”就会了
1.1 一个最简单的近似场景
先想象这样一个问题:你要计算 ( \sqrt{4.1} ) 的值。
如果按普通人的直觉,你会想:4.1 离 4 很近,( \sqrt{4}=2 ),那 4.1 的平方根大概是 2.025。这个估算过程,其实就暗含了泰勒展开的雏形:用一个已知点附近的信息,推断未知点的近似值。
数学家泰勒(Brook Taylor)在 1715 年前后提出了一件事:如果函数 $f(x)$ 在某个点 $x_0$ 附近足够光滑,那么可以用一个多项式去逼近它。这个多项式的每一项,都是根据函数在 $x_0$ 点处的导数构造出来的。
关键就在这里:小学二年级时你虽然没有背过泰勒公式,但已经做过无数次“近似估计”。泰勒展开不是一种全新的思维方式,而是把“近似估计”变成了一个可以精确控制误差的数学工具。
1.2 从“切线近似”到“多项式近似”
在高中阶段我们学过,函数在某一点的切线,是它附近最好的“直线近似”。
比如函数 $y = e^x$,在 $x=0$ 处的切线是 $y = 1 + x$。当 $x = 0.1$ 时,$e^{0.1} \approx 1 + 0.1 = 1.1$。实际计算一下,$e^{0.1} \approx 1.10517$,误差大约是 0.005,已经比较接近了。
但如果你想更精确怎么办?答案是用“曲线”去近似,而不是用“直线”。
泰勒展开做的事情,就是把“直线近似”推广成“二次曲线近似”“三次曲线近似”,甚至更高次的多项式近似。
- 零阶展开:用常数近似,$f(x) \approx f(x_0)$
- 一阶展开:用直线近似,$f(x) \approx f(x_0) + f'(x_0)(x - x_0)$
- 二阶展开:用抛物线近似,$f(x) \approx f(x_0) + f'(x_0)(x - x_0) + \frac{f''(x_0)}{2!}(x - x_0)^2$
阶数越高,局部逼近的效果通常越好。这个逻辑非常自然,你完全不需要把它想成一个从天而降的公式。
1.3 为什么程序员需要理解泰勒展开
很多开发者觉得泰勒展开是纯数学,和编程没有关系。但事实是,计算机里大量基础函数库的实现,就依赖泰勒展开(以及相关的级数展开)。例如:
- C 语言标准库中的
sin、cos、exp、log在部分实现中会使用多项式逼近; - GPU 上的 shader 中,很多超越函数为了性能会使用近似多项式;
- 机器学习里的梯度下降、牛顿法,底层都有泰勒展开的身影;
- 游戏物理引擎中,小角度近似会把 $\sin\theta \approx \theta$,这也是一阶泰勒展开。
可以说,泰勒展开是连接“数学模型”和“计算机数值计算”的一座重要桥梁。理解了它,你能看懂很多算法为什么会那样设计,也更容易定位一些数值异常问题。
2. 泰勒展开的核心公式与概念拆解
2.1 泰勒展开公式长什么样
设函数 $f(x)$ 在 $x_0$ 的某个邻域内具有 $n+1$ 阶导数,那么对于该邻域内的任一点 $x$,可以写成:
[ f(x) = f(x_0) + f'(x_0)(x - x_0) + \frac{f''(x_0)}{2!}(x - x_0)^2 + \cdots + \frac{f^{(n)}(x_0)}{n!}(x - x_0)^n + R_n(x) ]
其中 $R_n(x)$ 是余项,表示“用 n 次多项式近似后剩下的误差”。
如果使用等号,实际上应该写成:
[ f(x) = P_n(x) + R_n(x) ]
其中 $P_n(x)$ 就是泰勒多项式。通常在工程近似中,我们会忽略 $R_n(x)$,但心里必须清楚:忽略余项是有代价的。
2.2 每一项为什么是这样?
很多初学者被这个公式劝退,是因为不理解为什么会有 $n!$(阶乘)出现。
可以这样理解:假设我们想用一个 $n$ 次多项式来拟合 $f(x)$:
[ P_n(x) = a_0 + a_1(x - x_0) + a_2(x - x_0)^2 + \cdots + a_n(x - x_0)^n ]
我们希望这个多项式在 $x_0$ 点处的各阶导数和原函数完全一致:
[ P_n(x_0) = f(x_0) ] [ P_n'(x_0) = f'(x_0) ] [ P_n''(x_0) = f''(x_0) ]
对 $P_n(x)$ 求导可以发现,第 $k$ 项 $a_k(x - x_0)^k$ 求 $k$ 阶导后是:
[ a_k \cdot k! ]
为了让它等于 $f^{(k)}(x_0)$,自然有:
[ a_k = \frac{f^{(k)}(x_0)}{k!} ]
所以阶乘不是人为设定的,而是求导过程中自然产生的。这个解释如果你能想明白,泰勒公式就不再是一堆死记硬背。
2.3 麦克劳林展开
当 $x_0 = 0$ 时,泰勒展开的简化版本叫麦克劳林展开:
[ f(x) = f(0) + f'(0)x + \frac{f''(0)}{2!}x^2 + \cdots + \frac{f^{(n)}(0)}{n!}x^n + R_n(x) ]
在计算机计算中,麦克劳林展开非常常用,因为很多函数在 0 点处的导数非常好求。
2.4 余项与误差控制
余项 $R_n(x)$ 有多种形式,最常用的是拉格朗日余项:
[ R_n(x) = \frac{f^{(n+1)}(\xi)}{(n+1)!}(x - x_0)^{n+1} ]
其中 $\xi$ 是 $x_0$ 和 $x$ 之间的某个数。拉格朗日余项的价值在于,它能帮助我们估算误差的上界,虽然在实际工程中很难精确求出 $\xi$,但我们可以根据导数的取值范围估算误差范围。
比如在金融工程、物理模拟中,如果需要在某个精度范围内做近似,通常就会先用拉格朗日余项判断需要展开到多少阶,然后才去写代码。这一点很多开发者容易忽略,导致近似误差失控。
3. 几个重要的展开式与手算示例
3.1 必须背下来的四个展开式
在工程和算法面试中,下面四个展开式出现频率极高:
指数函数:
[ e^x = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots = \sum_{n=0}^{\infty} \frac{x^n}{n!} ]
正弦函数:
[ \sin x = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \cdots ]
余弦函数:
[ \cos x = 1 - \frac{x^2}{2!} + \frac{x^4}{4!} - \frac{x^6}{6!} + \cdots ]
对数函数:
[ \ln(1+x) = x - \frac{x^2}{2} + \frac{x^3}{3} - \frac{x^4}{4} + \cdots \quad (-1 < x \leq 1) ]
注意 $\ln(1+x)$ 的收敛区间是 $(-1, 1]$,如果 $x$ 的绝对值接近或超过 1,直接展开会发散,工程中通常需要先做变量变换。
3.2 手算示例:用二阶泰勒展开估算 $\sqrt{4.1}$
回到开头的例子。
设 $f(x) = \sqrt{x}$,取 $x_0 = 4$。
一阶导数: [ f'(x) = \frac{1}{2\sqrt{x}} ] 在 $x_0=4$ 处: [ f'(4) = \frac{1}{4} ]
二阶导数: [ f''(x) = -\frac{1}{4x^{3/2}} ] 在 $x_0=4$ 处: [ f''(4) = -\frac{1}{32} ]
于是二阶泰勒展开是: [ \sqrt{x} \approx \sqrt{4} + \frac{1}{4}(x - 4) - \frac{1}{64}(x - 4)^2 ]
代入 $x = 4.1$: [ \sqrt{4.1} \approx 2 + \frac{1}{4} \times 0.1 - \frac{1}{64} \times 0.01 ] [ = 2 + 0.025 - 0.00015625 = 2.02484375 ]
计算器给出的真实值是 $2.024845673\cdots$,误差不到小数点后第五位。这说明二阶展开已经能提供非常好的近似。
3.3 手算示例:用泰勒展开计算 $e^{0.1}$
对于 $f(x) = e^x$ 在 $x_0 = 0$ 处展开:
[ e^{0.1} \approx 1 + 0.1 + \frac{0.01}{2} + \frac{0.001}{6} ] [ = 1 + 0.1 + 0.005 + 0.0001667 = 1.1051667 ]
实际值: [ e^{0.1} = 1.105170918\cdots ]
取到三次项时,误差已经小于 $5 \times 10^{-6}$。这个手算过程展示了泰勒展开在“没有计算器”时的强大之处,也是很多数值算法的基础思路。
4. 用 Python 亲手验证泰勒展开
这一节我们进入实操。我会用 Python 分别演示:
- 用
sympy符号计算库直接求泰勒展开式; - 用
matplotlib画图比较原始函数与不同阶数展开式的逼近效果; - 手动实现一个三角函数的近似函数,模拟库函数的底层思路。
4.1 环境准备
本文示例使用以下环境:
- Python 3.8+(示例基于 3.10 验证通过)
- sympy 1.11+
- matplotlib 3.6+
- numpy 1.23+
如果你的环境中没有安装这些库,可以用 pip 安装:
pip install sympy matplotlib numpy版本不需要和上面完全一致,只要不低于要求即可。下文重点演示的是代码逻辑和泰勒展开的收敛规律,版本差异不影响运行效果。
4.2 使用 sympy 求泰勒展开式
先来看符号计算的写法。
# 文件路径:taylor_sympy.py import sympy as sp x = sp.symbols('x') # 对 e^x 在 x=0 处展开到 5 阶 expr1 = sp.exp(x) taylor1 = sp.series(expr1, x, 0, 6) # 第4个参数 6 表示展开到 x^5 print("e^x 在 x=0 处展开到 x^5:") print(taylor1) print() # 对 sin(x) 在 x=0 处展开到 7 阶 expr2 = sp.sin(x) taylor2 = sp.series(expr2, x, 0, 8) print("sin(x) 在 x=0 处展开到 x^7:") print(taylor2) print() # 对 ln(1+x) 在 x=0 处展开到 5 阶 expr3 = sp.log(1 + x) taylor3 = sp.series(expr3, x, 0, 6) print("ln(1+x) 在 x=0 处展开到 x^5:") print(taylor3)运行这段代码,你会得到类似下面的输出:
e^x 在 x=0 处展开到 x^5: 1 + x + x**2/2 + x**3/6 + x**4/24 + x**5/120 + O(x**6) sin(x) 在 x=0 处展开到 x^7: x - x**3/6 + x**5/120 - x**7/5040 + O(x**8) ln(1+x) 在 x=0 处展开到 x^5: x - x**2/2 + x**3/3 - x**4/4 + x**5/5 + O(x**6)其中O(x**6)表示余项是 $x^6$ 级别的小量,通常称为皮亚诺余项的写法。如果你想去掉余项,只看多项式部分,可以使用sp.removeO():
taylor1_poly = sp.series(expr1, x, 0, 6).removeO() print(taylor1_poly)输出:
x**5/120 + x**4/24 + x**3/6 + x**2/2 + x + 1在工程计算里,这种符号展开可以用来推导近似公式,例如在推导小角度单摆运动方程时,直接对 $\sin\theta$ 做一阶展开,就能得到线性化的微分方程。
4.3 用 numpy 和 matplotlib 观察收敛效果
接下来我们写一段绘图脚本,对比 $e^x$ 在 $x=0$ 附近的真实曲线,以及用不同阶泰勒多项式逼近的效果。
# 文件路径:taylor_plot.py import numpy as np import matplotlib.pyplot as plt def taylor_exp(x, n): """ 计算 e^x 在 x=0 处的 n 阶泰勒展开。 n=0 表示只取常数项,n=1 表示取到 x 项,以此类推。 """ result = 0.0 for k in range(n + 1): result += x**k / np.math.factorial(k) if hasattr(np, 'math') else x**k / np.math.factorial(k) return result这段代码里对阶乘的处理不够优雅,实际上numpy并没有math子模块。更稳妥的写法是用 Python 标准库math.factorial:
# 文件路径:taylor_plot.py import numpy as np import matplotlib.pyplot as plt import math def taylor_exp(x, n): """ 计算 e^x 在 x=0 处的 n 阶泰勒展开。 n=0 表示只取常数项,n=1 表示取到 x 项,以此类推。 """ result = 0.0 for k in range(n + 1): result += x**k / math.factorial(k) return result x = np.linspace(-3, 3, 400) y_true = np.exp(x) plt.figure(figsize=(10, 6)) plt.plot(x, y_true, 'k-', linewidth=2, label='true e^x') for n in [1, 2, 3, 5]: y_approx = [taylor_exp(xi, n) for xi in x] plt.plot(x, y_approx, '--', linewidth=1.5, label=f'Taylor n={n}') plt.ylim(-2, 8) plt.axhline(0, color='gray', linewidth=0.5) plt.axvline(0, color='gray', linewidth=0.5) plt.title('Comparison of e^x and Taylor Expansions') plt.xlabel('x') plt.ylabel('y') plt.legend() plt.grid(True, linestyle=':', alpha=0.6) plt.show()运行这段代码,你可以看到:
- 在 $x=0$ 附近,所有展开式都贴合得很好;
- 展开阶数越高,贴合区间越宽;
- 当 $x$ 偏离 0 较远时,低阶展开会迅速发散。
这说明泰勒展开本质上是一种“局部近似”,离展开中心越远,误差越大。工程上如果要在大范围内使用近似公式,通常需要分区间展开,而不是只取一个点作为展开中心。
4.4 手动实现一个正弦近似函数
计算机里的sin函数底层实现虽然不完全是套用泰勒公式,但多项式逼近思想是一致的。下面我们手动实现一个基于泰勒展开的近似正弦函数,精度足够满足演示需求。
# 文件路径:my_sin.py import math def my_sin(x, terms=10): """ 使用泰勒展开计算 sin(x),x 为弧度。 terms 表示参与计算的项数,默认取 10 项。 """ result = 0.0 for k in range(terms): coefficient = (-1) ** k exponent = 2 * k + 1 result += coefficient * (x ** exponent) / math.factorial(exponent) return result # 测试 test_values = [0.0, 0.1, 0.5, 1.0, 1.5] for v in test_values: approx = my_sin(v, terms=10) real = math.sin(v) print(f"x={v:5.2f} my_sin={approx:.12f} math.sin={real:.12f} 误差={abs(approx - real):.12e}")预期输出类似:
x= 0.00 my_sin=0.000000000000 math.sin=0.000000000000 误差=0.000000000000e+00 x= 0.10 my_sin=0.099833416647 math.sin=0.099833416647 误差=0.000000000000e+00 x= 0.50 my_sin=0.479425538604 math.sin=0.479425538604 误差=0.000000000000e+00 x= 1.00 my_sin=0.841470984808 math.sin=0.841470984808 误差=0.000000000000e+00 x= 1.50 my_sin=0.997494986604 math.sin=0.997494986604 误差=1.110223024625e-16从结果看,10 项展开在 $[-1.5, 1.5]$ 范围内的误差已经接近浮点数精度极限。但如果把 $x$ 扩大到 10,直接展开可能误差很大。这就是为什么实际库函数会先通过“参数约减”,把角度变换到 $[-\pi/2, \pi/2]$ 附近再使用多项式逼近。
你可以把terms改小,比如 2 或 3,观察近似效果的变化,这样可以直观理解“阶数越高,误差越小”这个结论。
5. 泰勒展开在工程中的典型应用与思考
5.1 数值计算库中的多项式逼近
在计算机出现早期,计算 $\sin x$、$e^x$ 这类函数时,硬件没有专用指令,软件层面只能依赖级数展开。现代 libm 虽然使用了更加复杂的 minimax 多项式,但其思想仍然是“用一个多项式在某个区间内尽量逼近目标函数”。
这一点对性能敏感的 C/C++ 程序有直接启发:如果你的程序需要高频调用sin、exp、log,但精度要求不高,可以考虑提前用泰勒展开或查表法实现自己的近似版本,以换取更高的吞吐量。不过要小心,这属于典型的“用精度换性能”的取舍,必须经过性能测试和误差测试,不能一拍脑袋就替换掉标准库函数。
5.2 机器学习与最优化:从梯度到二阶近似
机器学习中,模型训练的核心是参数优化。以梯度下降为例:
[ \theta_{t+1} = \theta_t - \eta \nabla f(\theta_t) ]
这个公式实际上可以理解为对损失函数 $f(\theta)$ 在 $\theta_t$ 处做一阶泰勒展开,然后沿负梯度方向迈出一步。如果保留二阶项,就会得到牛顿法:
[ \theta_{t+1} = \theta_t - \eta [H f(\theta_t)]^{-1} \nabla f(\theta_t) ]
其中 $H f$ 是 Hessian 矩阵。二阶方法收敛更快,但计算 Hessian 的开销太大,所以实际中有大量近似技巧(例如 BFGS、L-BFGS)都在用低秩或历史梯度信息近似二阶信息。
如果你在阅读优化算法论文时觉得“梯度下降”和“牛顿法”的来龙去脉不清晰,可以从泰勒展开的角度重新整理一遍,会发现这些方法本质上都是“用局部多项式近似损失函数,然后去求近似函数的最小值”。
5.3 小角度近似与物理引擎
在游戏开发和机器人控制中,经常遇到如下的简化:
[ \sin\theta \approx \theta, \quad \cos\theta \approx 1 - \frac{\theta^2}{2} ]
这就是麦克劳林展开的低阶形式。当 $\theta$ 很小时,这种近似能极大简化计算,尤其在实时物理模拟中,每一帧都要处理大量刚体运动。只要角度处于较小范围,近似的误差肉眼不可见。
但这里有一个工程陷阱:如果物体旋转速度很快,或者经过极端状态,$\theta$ 不再是小量,继续使用小角度近似会出现明显的“飘移”或能量不守恒现象。此时就应该换用更高阶展开,或者干脆使用严格的三角函数计算。
5.4 金融衍生品定价中的解析近似
金融工程中,很多期权定价模型没有解析解。一个典型的做法是在某个基准参数附近做泰勒展开,得到近似解析表达式,从而避免耗时的蒙特卡洛模拟。
例如,当波动率微小变动时,期权价格的变化可以用 Delta、Gamma 这些希腊字母来描述:
[ P(\sigma + \Delta\sigma) \approx P(\sigma) + \frac{\partial P}{\partial \sigma} \Delta\sigma + \frac{1}{2}\frac{\partial^2 P}{\partial \sigma^2}(\Delta\sigma)^2 ]
这其实就是泰勒展开在金融风险度量中的直接应用。理解这一点,对做量化风控、衍生品定价的开发者会很有帮助。
6. 常见误区与 FAQ
6.1 泰勒展开和泰勒级数是一回事吗?
严格来说,“泰勒展开”是指把函数在某点附近表示成一个有限项多项式加余项;而“泰勒级数”是指当项数趋于无穷时的级数形式。工程中经常不严格区分,但心里要清楚:有限项是近似,无限项才可能严格相等。
6.2 所有函数都能做泰勒展开吗?
不是。函数必须在展开点处有足够阶的导数。如果函数在某点不连续、不可导,或者函数虽然有任意阶导数但泰勒级数收敛不到自身,就不能直接展开。
最经典的例子是:
[ f(x) = \begin{cases} e^{-1/x^2}, & x \neq 0 \ 0, & x = 0 \end{cases} ]
这个函数在 $x=0$ 处的所有导数都是 0,所以它在 0 点的泰勒级数恒为 0,但它本身并不是 0 函数。这就是“无穷阶可导”不等于“能展开成泰勒级数并收敛到原函数”的典型反例。工程中大多数常见函数不存在这个问题,但理解这一边界能避免在一些特殊模型上踩坑。
6.3 展开阶数越高越准吗?
在展开点附近,通常是的。但如果距离展开点过远,高阶项可能因为 $x^k$ 的快速增长而导致多项式数值爆炸,这时增加阶数反而会让误差变大。
例如 $e^x$ 在 $x=10$ 处取 10 阶展开,和取 3 阶展开比,10 阶误差可能反而更大。实际工程中要根据 $x$ 的范围选择合适的阶数,或者干脆换一个展开中心。
6.4 余项在工程中怎么处理?
工程中不会每次都用拉格朗日余项去精确计算误差边界。更好的做法是:
- 先用粗略的理论分析确定大致的展开阶数;
- 再用数值实验检查最大误差;
- 最后根据误差阈值决定是否提高阶数。
我把这种情况整理成一个简单的排查思路表格:
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 近似结果偏差大 | 展开中心离目标点太远 | 更换展开中心或缩小 $x-x_0$ |
| 增加阶数后误差反而增大 | 高阶项数值溢出或区间过大 | 控制使用区间,或做参数约减 |
| 在边界处出现剧烈振荡 | 级数收敛半径太小 | 换用其他逼近方法,如切比雪夫多项式 |
| 函数不可导或特殊点附近失真 | 展开点不满足可导条件 | 检查函数定义域,重新选择展开中心 |
| 近似公式在极端参数下失效 | 没有考虑参数变化范围和误差控制 | 加入误差测试和参数边界检查 |
7. 工程实践中的建议与学习路线
7.1 把泰勒展开当成“分析工具”而非“计算负担”
很多初学者把泰勒展开理解成“考试时用来求极限的公式”,这太窄了。在工程中,泰勒展开是一种分析工具,用于:
- 判断一个系统在某个工作点附近的线性稳定性;
- 简化复杂的非线性模型;
- 推导算法迭代公式;
- 估计某些计算方法的误差量级。
所以学习时不要只背公式,可以试着用泰勒展开去推导一遍梯度下降、牛顿法、小角度近似这些工程中常见的结论,理解会比死记硬背牢固得多。
7.2 代码中避免直接滥用泰勒展开
虽然泰勒展开思想很好,但在实际代码中我并不建议你轻易手写一堆x**n / factorial(n)去替代标准库函数。原因包括:
- 标准库已经经过充分优化和测试;
- 手写展开式容易忽略浮点误差累积;
- 方案的收敛区间需要严格验证,代码维护成本高。
如果你的确需要在特定场景下使用泰勒展开,比如在 GPU shader 中做低成本近似,建议遵循以下步骤:
- 明确输入参数的数值范围;
- 选择适当的展开中心和阶数;
- 编写误差测试用例,与高精度标准结果对比;
- 在真实负载下做性能基准测试;
- 把近似的适用范围和精度指标写进注释。
7.3 学习路线:从直观理解到深入细节
如果你想继续深入,可以按下面的顺序学习:
- 先理解“用多项式逼近函数”的几何直觉;
- 亲手推导 $e^x$、$\sin x$、$\cos x$、$\ln(1+x)$ 的展开式;
- 用 Python 画图直观感受不同阶数的逼近效果;
- 学习拉格朗日余项、皮亚诺余项的联系与区别;
- 学习“收敛半径”的概念,理解为什么 $\ln(1+x)$ 只能在 $(-1,1]$ 内展开;
- 进一步了解傅里叶级数,那是用“三角函数”逼近函数的另一个分支;
- 了解 minimax 逼近、切比雪夫逼近等现代数值方法。
这里最值得推荐的练习是:自己写一个my_exp函数,然后用它实现随机数的指数分布采样,和numpy.random.exponential的结果对比误差。这个过程会逼你真正理解展开项数、数值范围、误差控制之间的关系,比单纯刷题有效得多。
写这篇长文的契机,是我最近在一个实时渲染项目里想用低阶多项式代替高开销的次方计算。最初直接套了一阶展开,结果边缘光斑失真严重,后来才意识到必须在合适的展开中心、合适的阶数和误差验证之间做权衡。泰勒展开这套数学工具本身并不神秘,真正需要修炼的是:知道什么时候该用它,什么时候不该用,以及用了之后如何验证它没有在边界情况下悄悄背叛你。如果你能亲手跑一遍上面几段代码,再去观察一下标准库函数在不同区间下的误差变化,对“近似”这件事的理解,应该会上一个台阶。