# 符号 vs 数值 · 何时用哪个，以及怎么合体

> 符号计算精确但可能爆炸，数值计算高效但有误差——它们是一对互补的世界观。这一章给出清晰的决策框架：什么时候用符号、什么时候用数值，以及那个把两者优点合一的杀手锏：lambdify——先符号推导公式，再编译成飞快的数值函数。

- 作者：David（道雾轩）
- 专栏：符号计算的艺术（https://daiw.org/manual/symbolic-computing.md）
- 最后更新：2026-07-14
- 原文：https://daiw.org/manual/symbolic-computing/symbolic-vs-numeric
- 转载与引用：请注明出处并附原文链接（https://daiw.org/about/copyright）

# 符号 vs 数值 · 何时用哪个，以及怎么合体

走到这里，符号计算的能力与软肋你都见过了。是时候把它和它的[孪生兄弟——数值计算](https://daiw.org/manual/numerical-computing)摆在一起，回答那个最实际的问题：**手上的活儿，该用哪个？** 答案不是「二选一」，而是「看情况，还能合体」。

## 两种世界观

先把两者的性格并排看清：

| | 符号计算 | 数值计算 |
| --- | --- | --- |
| 处理对象 | [精确表达式](https://daiw.org/manual/symbolic-computing/exact-numbers) | [近似浮点数](https://daiw.org/manual/numerical-computing/floating-point) |
| 给出 | **公式 / 精确解** | **具体的数** |
| 误差 | **零** | 有[舍入 / 截断误差](https://daiw.org/manual/numerical-computing/machine-epsilon) |
| 速度 | 慢，有时极慢 | **快** |
| 内存 | 可能[爆炸](https://daiw.org/manual/symbolic-computing/expression-swell) | 固定、可控 |
| 可扩展性 | 差（变量一多就跪） | **好**（百万维照跑） |
| 洞察 | 看清**结构与规律** | 只见**一个个数** |

一句话：**符号追求「对与懂」，数值追求「快与大」。** 它们各自的强项，正是对方的软肋。

## 什么时候用符号

选**符号**，当你要的是「精确」或「公式」：

- **需要一个公式**，而非某点的数（推导求根公式、导出解析解、化简表达式）。
- **需要精确答案**（数论、密码学、几何证明，差一点都不行）。
- **要理解结构**：这个积分有没有初等形式？这族矩阵何时奇异？方程有几个根？
- **问题规模小**、变量少（符号方法在小问题上才跑得动）。
- **验证与教学**：用精确解检验数值程序对不对；把推导展示给人看。

## 什么时候用数值

选**数值**，当你要的是「快」或「大」，或者符号根本无能为力：

- **大规模**：百万维线性方程组、大矩阵——符号[必然膨胀](https://daiw.org/manual/symbolic-computing/expression-swell)，只能数值。
- **没有闭式解**：大多数[非线性 ODE](https://daiw.org/manual/symbolic-computing/symbolic-ode)、真实世界的模型，符号解**不存在**，只能[数值逼近](https://daiw.org/manual/numerical-computing/ode-euler-rk)。
- **真实数据**：带噪声的实测数据，本就没有「精确」可言，该[拟合](https://daiw.org/manual/numerical-computing/splines-lsq)而非求解。
- **性能关键**：要在毫秒内、或对海量点求值（实时系统、仿真、训练模型）。

## 杀手锏：lambdify，让两者合体

最妙的是，你**不必二选一**。科学计算里最高效的套路，是**先用符号推导、再用数值求值**——SymPy 的 `lambdify` 正是这座桥：

<Callout type="info">
  **`lambdify` 把一个符号表达式，「编译」成一个飞快的数值函数（通常基于 NumPy）。** 于是你能：**用符号计算做它最擅长的——精确推导出公式（比如求个导、解个方程、化个简）；再 `lambdify` 成数值函数，交给 NumPy 在百万个点上飞速求值。** 符号的「对与懂」+ 数值的「快与大」，一举两得：

  ```python
  from sympy import *
  import numpy as np

  x = symbols('x')
  expr = diff(sin(x**2), x)          # ① 符号求导:精确得到 2*x*cos(x**2)
  f = lambdify(x, expr, 'numpy')     # ② 编译成基于 NumPy 的快速函数

  f(np.array([1.0, 2.0, 3.0]))       # ③ 数值批量求值 → [1.081, -2.615, -5.467]
  ```

  这就是「合体」的威力：导数的**公式**由符号保证正确（不受[数值微分 U 形误差](https://daiw.org/manual/numerical-computing/differentiation)之苦），而海量点的**求值**由 NumPy 保证飞快。深度学习框架的 autodiff、科学计算里「推公式 + 跑数据」的工作流，骨子里都是这个思路。**先符号、后数值，是行家的默认套路。**
</Callout>

## 一张决策图

```mermaid
flowchart TD
    Q["手上的问题"] --> A{"需要精确解 / 公式?"}
    A -->|是| B{"规模小、且解存在?"}
    A -->|否, 要快/要大| N["数值计算<br/>NumPy / SciPy"]
    B -->|是| S["符号计算<br/>SymPy / Mathematica"]
    B -->|否, 会膨胀或无闭式| N
    S -.用 lambdify 求值.-> N
    N -.用符号验证/推导.-> S
```

符号与数值不是敌人，而是一枚硬币的两面。**懂得在它们之间自如切换、乃至用 `lambdify` 让它们协作，是「科学计算」这门手艺真正的成熟标志。**

## 小结与下一站

**符号 vs 数值，是「对与懂」vs「快与大」**：符号精确、给公式、看清结构，但慢且易[膨胀](https://daiw.org/manual/symbolic-computing/expression-swell)；数值高效、可扩展，但有误差、只给数。**要公式 / 精确 / 小规模 / 理解结构 → 符号；要速度 / 大规模 / 无闭式 / 真实数据 → 数值。** 最高效的是**合体**：`lambdify` 先符号推导公式、再编译成 NumPy 函数飞速求值——先符号、后数值。

全篇的能力、软肋、取舍都讲透了。最后一章，我们把这一路的主线——**表达式树、规则重写、精确的代价、以及「计算即符号变换」的本质**——收拢成一张全景图。👉 [收尾：一张图串起全篇](https://daiw.org/manual/symbolic-computing/recap)。

## 参考文献

- [1] SymPy 文档.「lambdify — Numeric Computation.」https://docs.sympy.org/latest/modules/utilities/lambdify.html
- [2] Meurer et al.「SymPy: symbolic computing in Python.」*PeerJ CS*, 2017. —— 符号与数值的桥接。
- [3] 参见孪生专栏《[数值计算的艺术](https://daiw.org/manual/numerical-computing)》—— 数值方法的完整图景。
