你是否遇到过:数学上收敛于6的迭代,程序却稳定输出100?一个简单的多项式,计算结果与真实值相差10²¹倍?大模型在基础数学运算上频频出错?
这不是代码bug,而是浮点计算的误差被放大所致。
一、问题的严重性:从“蝴蝶效应”到航天痛点
上世纪60年代,气象学家洛伦兹在计算机上进行天气模拟时,将 0.506127 四舍五入为 0.506,这个微小的舍入误差,却导致长期天气预报结果截然不同。他由此提出了“蝴蝶效应”——初始条件的微小变化,可能导致系统长期行为的巨大偏离。
这一发现,本质上揭示了数值计算中初始舍入误差被迭代放大的灾难性后果。然而,从洛伦兹的发现至今已近七十年,这一问题在工程实践中仍未得到根本解决。根据《中国科学:技术科学》(2015,探月三期专辑)的总结,误差问题是影响航天嵌入式软件可信的十大核心问题之一。
虽然这一问题是航天领域的公认痛点,但它同样存在于科学计算、人工智能、金融建模、工业仿真等广泛领域。在这些领域的关键场景中,看似微小的浮点舍入误差,同样可能通过迭代或病态表达式被指数放大,导致软件输出“逻辑正确但结果完全错误”。
二、三个层面的数值陷阱
数值计算的不稳定性并非偶发,而是存在于从底层到顶层的三个层次:
🔢 第一层:底层数学库函数的精度偏差
标准数学库函数(包括幂指数函数、三角/反三角函数、对数函数等)中,许多函数的结果都存在不可忽视的误差。例如:
- 对于
exp(x),若x有几位整数,其结果中往往就有几位错误数字; - 有些问题本身要求输入具有较高精度,这时误差可能极大(如
cos(39.2699082),其输出中的错误数字超过一半); - 当输入极大或极小时,甚至可能完全错误(如符号相反)。
这意味着,即使是最基础的数学运算,也可能在用户毫不知情的情况下给出错误结果。
🧪 第二层:算术表达式的错误计算
即使是看似简单的多项式,计算机也可能算错。例如,考虑以下表达式:
674575
×
123
12
−
82972725
×
123
11
−
117
×
123
2
+
1770329.46
674575 × 123^{12} - 82972725 × 123^{11} - 117 × 123^2 + 1770329.46
674575×12312−82972725×12311−117×1232+1770329.46
其数学精确值为 236.46。然而,在双精度浮点下计算,得到的结果却是 1.1259E+15——完全错误,量级相差 10¹³。表达式仅含乘法和加减法,却因大数相消导致彻底失效。
🔁 第三层:循环迭代的误差指数放大
考虑一个简单的迭代:
{
y
1
=
234.56
y
n
=
12345
×
sin
(
y
n
−
1
)
,
n
≥
2
\begin{cases} y_1 = 234.56 \\ y_n = 12345 \times \sin(y_{n-1}), & n \ge 2 \end{cases}
{y1=234.56yn=12345×sin(yn−1),n≥2
迭代 5 次后,数学精确值约为 -7053。然而,在任何使用双精度浮点数的软件(如 Excel、Python、C 等)中计算,得到的结果都是约 12199——符号完全相反,数值也相差甚远。微小的舍入误差在迭代中被逐次放大,导致结果彻底偏离理论。
三、教学包简介
《可信软件中的数值计算陷阱与验证实验包》是一个面向软件工程、AI开发者的开源教学资源,从上述三个层次揭示数值计算的可信性问题。
项目地址:https://gitee.com/verified-numerics/verified-numerics
教学包特色
- 完整讲义:每个实验都有详细的
handout.md,包含理论讲解、案例分析和思考题 - 可运行代码:提供 Python 演示脚本,学生可直接运行验证
- 参考答案:所有思考题和探究任务都有参考答案
- 可信验证工具:集成 ISReal 在线服务,可对比普通浮点结果与可信结果
适用人群
- 软件工程、计算机科学与技术专业师生
- AI 算法工程师、算子开发者
- 对数值计算可信性感兴趣的研究者
- 航天、金融等安全攸关领域的软件工程师
四、教学包内容概览
| 实验 | 核心问题 | 教学价值 |
|---|---|---|
| 实验0:数学库函数 | 标准库函数为何也会出错? | 建立 “误差几近无处不在” 的意识 |
| 实验一:Rump 函数 | 算术表达式为何结果完全错误? | 建立 “高精度 ≠ 可信” 的认知 |
| 实验二:循环迭代 | 逻辑正确的迭代为何收敛到错误值? | 理解 误差动态累积机制(错数 > 0) |
五、快速开始
无需克隆整个仓库,你可以直接在线浏览核心文档:
- 项目总览 README —— 完整介绍、实验概览、使用指南
- 实验0:数学库函数 —— 揭示
exp(x)、sin(x)、pow(x,y)等的精度偏差 - 实验一:Rump 函数 —— 展示大数相消导致的灾难性错误
- 实验二:循环迭代 —— 演示微小误差如何被指数放大
如果你想本地运行代码,可以克隆仓库:
git clone https://gitee.com/verified-numerics/verified-numerics.git
六、延伸资源
教学包还包含以下进阶文档:
- 面向AI工程师的数值计算指南 —— 深度学习中的数值陷阱
- 大模型数值计算失败案例集 —— 大模型在基础数学运算上的错误实证
- 从“猜精度”到“保正确”:论误差可控计算的必要性 —— 传统高精度库的系统性缺陷
- 历史上因数值计算错误引发的灾难与事件 —— 从洛伦兹到爱国者导弹
七、结语
数值计算的可信性是软件可靠性的重要基石。在软件定义一切的今天,让软件工程师掌握误差分析、具备可信计算意识,已刻不容缓。
本教学包已完成开发,欢迎高校教师试用,也期待收到宝贵的反馈意见!
项目地址:https://gitee.com/verified-numerics/verified-numerics
💡 教学使命:让学生从“玩具案例”理解“航天级风险”,培养编写不仅正确、而且可信的软件的能力。

444

被折叠的 条评论
为什么被折叠?



