首页 › programming › 0.1加0.2为何不等于0.3

0.1 + 0.2 为什么不等于 0.3:一条浮点数神课深度解读

为什么值得读这篇文章

几乎每个程序员都在职业生涯的某个瞬间撞见过这个灵异事件:0.1 + 0.2 的结果不是 0.3,而是 0.30000000000000004。大多数人耸耸肩背下“浮点有误差”这句话就翻篇了,但极少有人真正弄懂误差从哪里来、为什么会是这个形状、以及它什么时候会咬你一口。Computerphile 频道的经典讲解视频《Floating Point Numbers》(浮点数)就是补上这一课的最佳入口——它用一支笔、一张纸,把“计算机如何存放小数”这件事讲得连非程序员都能听懂。而在 2025–2026 年,随着 AI 芯片的精度大战(FP16、BF16、FP8 甚至 FP4)登上主流媒体,浮点格式第一次从教科书走进了大众视野:理解这条视频,等于同时理解了“为什么 0.1 加 0.2 会错”和“为什么 AI 芯片要靠降精度换算力”这两件看似无关的事。

视频基本信息

项目 内容
视频标题 Floating Point Numbers(浮点数)
频道 Computerphile
发布时间 2014 年(据频道页面历史信息)
播放量 百万级常青经典(据频道页面历史数据)
时长 约 10 分钟
观看方式 YouTube 站内搜索 "Floating Point Numbers Computerphile" 即可达

注:本表据频道页面与公开资料整理。本次发布环境网络受限,未能实时复核播放量与发布日期的精确值,引用前请以 YouTube 频道页面实时数据为准。

核心主张拆解:十分钟讲清计算机的“小数谎言”

这条视频的叙事结构非常克制,基本上是一条主线走到底,可以拆成五个要点。

要点一:计算机里根本没有“小数点”

视频开篇先把观众拉回到最底层:计算机只认识 0 和 1,所有数——包括“小数”——最终都必须用二进制表示。我们习惯的十进制小数(比如 0.1)在二进制世界里并不是一个自然的对象。二进制小数点的每一位代表的不是十分之一、百分之一,而是二分之一、四分之一、八分之一:0.1₂ = 1/2,0.01₂ = 1/4,0.101₂ = 5/8。

由此立刻推出一个关键事实:只有分母是 2 的幂的分数,才能在二进制里写成有限小数。0.5(二进制 0.1)、0.25(0.01)、0.375(0.011)都是“好数”;而 0.1 在二进制下是 0.00011001100110011...——0011 无限循环,就像 1/3 在十进制下是 0.3333... 一样。这就是一切问题的总根源:你想存进去的数,从一开始就存不进去。

要点二:定点数太浪费,浮点数登场

如果给二进制小数点固定一个位置(比如前 16 位是整数部分、后 16 位是小数部分),就是“定点数”。视频用很直观的方式点出定点数的死穴:它能表示的数的范围和精度被死死焊住——你要么只能表示很小的数,要么在很大和很小之间顾此失彼,而位宽是花钱买来的,浪费不起。

解法是借鉴科学计数法。十进制的 300000000 可以写成 3.0 × 10⁸,二进制同理:任何一个数都可以拆成符号(正负)、指数、尾数三段。因为二进制规范化后尾数的第一位永远是 1(就像十进制科学计数法的第一位永远不是 0),这位 1 甚至不用存——这就是大名鼎鼎的“隐藏位”(implicit leading 1),凭空多赚一位精度。这种“小数点会浮动”的表示法,就叫浮点数。

要点三:32 位与 64 位的分账方式

视频接着给出工程上的分蛋糕方案,也就是 IEEE 754 标准的核心参数:

指数部分用“偏移码”存(双精度偏移 1023),目的是让指数可以顺畅地表示负数次幂。视频在这一段反复强调一个直觉:浮点的精度是“相对”的,不是“绝对”的——它保证的是有效数字位数,而不是小数点后的位数。数越大,相邻两个可表示的浮点数之间的空隙就越大。1.0 附近你能精细到万亿分之一,但在 2⁵³ 附近,相邻两个双精度数已经隔了 2。

要点四:误差是在“入库”那一刻产生的

理解了存储格式,0.1 + 0.2 ≠ 0.3 就不再神秘:0.1 写进内存时被四舍五入成最近的可表示值,0.2 同样被舍入过。你以为你在加 0.1 和 0.2,实际上你加的是两个“存得下的邻居”。加法本身没算错——错在源头。

要点五:对阶——浮点加法真正凶险的一步

视频最有含金量的一击在收尾:两个浮点数相加时,指数不同必须先“对阶”(aligning exponents)——把小指数那个数的尾数右移,直到两边指数一致。尾数只有 52 位,右移移出去的低位直接丢失(或按规则舍入)。两个数相差越大,小数被“挤掉”的有效位越多。这解释了很多反直觉现象:大数吃小数(在几亿级别的数上加 0.0001 可能毫无效果)、累加误差随次数增长、以及 0.1 + 0.2 的最终结果为什么是 0.30000000000000004 这么一个“差一点”的怪数——它是对阶、相加、再舍入三连之后离真值最近的可表示值。

知识与理论溯源:这条视频背后的真实谱系

视频是科普表达,但它脚下的每一层都有真实的标准、人物和事故。

IEEE 754 标准与 William Kahan。 1985 年发布的 IEEE 754 是浮点运算的统一标准,它终结了此前各家硬件各搞一套浮点、同一程序跨机器跑出不同结果的乱世。标准背后最关键的人物是伯克利大学教授 William Kahan,他因此获得 1989 年图灵奖,被业界称为“浮点数之父”。今天你无论用 x86、ARM 还是 GPU,浮点行为都能对齐,根基就是这套标准。视频讲的全部内容——符号、指数、尾数、隐藏位——都是 IEEE 754 的正文条款。

Goldberg 的传世论文。 1991 年,David Goldberg 在 ACM Computing Surveys 上发表《What Every Computer Scientist Should Know About Floating-Point Arithmetic》。三十多年过去,它仍是浮点领域的必读文献,"every computer scientist should know"这个标题本身就是一句提醒:这是每个写代码的人的必修课,而不是数值计算专家的选修课。

真实的工程事故。 浮点误差不是纸面担忧。1994 年英特尔 Pentium 芯片的 FDIV 除法指令查表表项有错,导致特定输入下除法结果错误,最终英特尔宣布召回并更换芯片,据当时媒体报道损失约 4.75 亿美元——一次表项错误,烧掉了几个月的利润。更隐蔽的是累积型误差:1982 年起加拿大温哥华证券交易所的指数用“截断到小数点后三位”的方式累加计算,每一步只丢掉不到半厘钱,但日积月累,据事后披露的重新核算,指数真实值几乎是显示值的两倍。这些案例共同印证了视频里那句轻描淡写的话:单次舍入可以忽略,误差是会复利的。

语言的现实。 ECMAScript 规范规定 JavaScript 的 Number 就是 IEEE 754 双精度——这是 JS 没有整数类型(在 Number 范围内)的根源,也是 Number.EPSILON 存在的原因。Python 的 float 同样是双精度,但标准库额外提供了 decimal(十进制浮点,金融友好)和 fractions(有理数,绝对精确)两个逃生舱。Java 则有 BigDecimal。金融系统普遍规定金额不用 float,用“以分为单位的整数”或十进制类型,正是这条视频内容的制度化体现。

AI 时代的续集。 最近几年,故事有了新篇章:AI 训练发现不需要 64 位的极端精度,Google Brain 团队推出 BF16(bfloat16,指数位与双精度对齐、尾数砍短),NVIDIA 的 H100、Blackwell 等数据中心芯片加入 FP8 甚至 FP4 支持——本质上就是把 IEEE 754 的“分蛋糕方案”重新切一次:尾数再少几位,换算力翻几倍。为什么尾数砍短是安全的?因为深度学习对相对误差天然宽容。你会发现,读懂了这条 2014 年的科普视频,就拿到了理解 2026 年芯片发布会参数表的钥匙。

批判性审查:哪些是事实,哪些是简化

这条视频作为入门材料质量极高,但以严谨标准看,有几处值得标出。

“计算机不能精确表示 0.1”是简化说法。 准确地说,是“IEEE 754 二进制浮点不能精确表示 0.1”。十进制的 decimal 类型可以精确存 0.1,Python 的 Fraction(1, 10) 更是绝对精确。误差不是“计算机”的宿命,而是一种特定的存储格式的设计代价。视频为了叙事流畅没有展开这一层,读者应补全。

“0.1 + 0.2 ≠ 0.3”的误差并非加法引入。 常见误解是把锅扣在加法器头上。实际上 0.1 和 0.2 在字面量解析阶段就各自被舍入了,相加之后的 0.30000000000000004 甚至是整个运算链里“最接近真实 0.3 的那个值”。换句话说,结果已经尽力了——是输入本身就带着伤。

视频没讲的部分恰好是生产环境的雷区。 至少有四块内容被省略:其一,IEEE 754 定义了 NaN、Infinity 和 ±0,0.0 / 0.0 得 NaN、NaN 不等于自身,而 -0.0 == 0.0 却为真,这些都是真实代码里的坑;其二,次正规数(subnormal)与渐进下溢,保证小到极值的过渡是平滑的;其三,求和顺序会改变结果——同样一亿个数,换个加法顺序误差可以差出几个量级,这也是 NumPy 的 sum 默认采用成对求和、Python 提供 math.fsum 精确求和的原因;其四,比较大小时应使用 Kahan 求和这类补偿算法,而不是简单累加。

科普类比的一处边界。 视频用“科学计数法”类比浮点,直观但有一处不严格:十进制科学计数法是人为书写约定,而浮点是带舍入规则的有限存储。类比能帮你理解结构,不能帮你预测某次具体运算舍到哪一位——预测那种问题要靠机器精度(双精度约 2.22×10⁻¹⁶)和相对误差分析,Goldberg 论文正是为此而写。

总体评价:视频在“为什么”层面证据充分、结论可靠;在“怎么办”层面只点到为止,需要读者自行补足工程实践。

认知提升与实用启示

第一,永远不要用 == 判断两个浮点数相等。 这是这条视频能直接兑换成代码习惯的一条。相等判断应改为“差的绝对值小于容差”,且注意大数要用相对容差——Python 3.5 起标准库直接给了 math.isclose(),JavaScript 里可以借助 Number.EPSILON 自行封装。凡是涉及浮点的单元测试,都应使用近似断言。

第二,钱永远不用 float 存。 金额要么用最小货币单位的整数(分、厘),要么用语言内置的十进制类型(Java 的 BigDecimal、Python 的 decimal)。温哥华交易所指数事故的教训可以浓缩成一句话:你以为丢的是零点几厘,市场替你把复利算回来。同理,任何“大量累加、长期累积、逐笔结算”的场景,都要在源头选择精确表示。

第三,读懂精度,就能读懂 AI 芯片的参数表。 下次看到 “FP8 算力是 FP16 的两倍”这类宣传,你能立刻看穿本质:尾数从 52 位砍到几位的代价是相对精度下降,收益是存储、带宽和乘法器的成本骤降。训练框架里混合精度(大权重用高位、梯度计算用低位)的取舍逻辑,全部建立在这条视频讲的那块“蛋糕”上。对小数表示法的理解,正在成为 AI 时代的基础素养——这是这条十年前的老视频在当下重新焕发热度的真正原因。

视频论证结构图

flowchart TD
    A["十进制 0.1"] --> B["二进制下无限循环"]
    B --> C["存不下 必须舍入"]
    C --> D["IEEE 754 双精度"]
    D --> E["1符号 11指数"]
    D --> F["52尾数 含隐藏位"]
    E --> G["0.1 存成近似邻居"]
    F --> G
    G --> H["0.2 同样被舍入"]
    H --> I["相加前先对阶"]
    I --> J["尾数右移 低位丢失"]
    J --> K["结果再舍入一次"]
    K --> L["0.30000000000000004"]
    L --> M["== 0.3 判定为假"]

延伸阅读

  1. David Goldberg, What Every Computer Scientist Should Know About Floating-Point Arithmetic(1991)— 浮点领域的“圣经”论文,本视频省略的 NaN、下溢、误差分析全部在此
  2. Python 官方文档《decimal — 十进制定点和浮点运算》— 金融与精确计算场景的标准答案,含与 float 的对比示例

参考来源

  1. Computerphile 频道主页 — 《Floating Point Numbers》视频出处频道,站内搜索视频标题可达
  2. YouTube 站内检索:Floating Point Numbers Computerphile — 直达该视频的检索入口
  3. David Goldberg 论文(Oracle 官方托管版) — 浮点运算经典文献全文
  4. Wikipedia: IEEE 754 — 浮点标准的历史与格式参数(符号/指数/尾数位数)
  5. Python 官方文档:decimal — 十进制精确运算的标准库文档

本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵爱卫生(微信ID: gprshome201101)维护,聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入