有用

代码与技术常识05 / 10

浮点数为什么不精确

0.1 + 0.2 ≠ 0.3:计算机存的小数只是近似值。

  • 学会用时30 分钟
  • 你的收获金额计算不再差一分钱
  • 用到的频率每周 2 次
  • 难度进阶

01为什么学

没学之前

算价格时 19.99 × 100 得到 1998.9999999999998,对账差一分钱。

学会之后

知道原因:金额用整数「分」存,比较小数不用 ===。

  • 金额、统计、比较都会避开坑
  • 理解 FP16、BF16 为什么是在拿精度换空间

02图解

流程图
  1. 1十进制 0.1想存起来
  2. 2转二进制0.0001100110011… 无限循环
  3. 3截断保存只存前 52 位
  4. 4读出来0.1000000000000000055…
  5. 5相加误差累积
不是计算机算错了,是它存的本来就是近似值。

03基本单元5 个

  • 二进制小数0.1 是无限循环
  • 双精度约 15–17 位有效数字
  • 误差约 1e-16
  • 整数分金额用整数存
  • 容差比较abs(a−b) < 1e-9

04怎么用

  1. 十进制的 0.1 在二进制里是无限循环小数,只能存近似值
  2. 金额用整数「分」存储,显示时再除以 100
  3. 比较两个小数,不用 ===,而是看差值是否小于一个很小的数
  4. 模型里的 FP32、FP16、BF16、FP8,就是用更少位数换内存和速度

05速查表

场景错误做法正确做法
金额用小数 19.99用整数 1999 分
比较a === babs(a − b) < 容差
显示直接输出格式化到 2 位
大批量求和逐个相加使用高精度库或先转整数

06动手试试

看看浮点数的真面目

07套用一次

19.99 × 100 = 1998.9999999999998;用 Math.round(19.99 * 100) = 1999 才对。

08常见的坑

  • 用小数存金额

    存整数的「分」,展示时再格式化。

  • 用 === 比较小数

    比较差值是否足够小。

09自测与练习

先做 10 秒自测,再动手练一下。

存金额更稳妥的方式是?

10 分钟小练习

在浏览器控制台输入 0.1 + 0.2,再试 19.99 * 100。

看参考答案
结果分别是 0.30000000000000004 和 1998.9999999999998。

+配合着学

代码与技术常识的全部 10 条