在线计算器 打开工具

0.1+0.2 为什么等于 0.30000000000000004

这不是计算器算错了,而是十进制小数在二进制里存不下。0.1 转成二进制是 0.0001100110011…(1100 无限循环),双精度只能截断到 53 位有效二进制位,于是参与运算的已经不是精确的 0.1。

误差是怎么被放大的

把一个十进制小数转成二进制,规则是「乘 2 取整」。0.1 会得到 0.000110011001100…,1100 这一段无限重复——和十进制里 1/3 = 0.333… 是同一类问题。

双精度(IEEE 754 binary64)只有 52 位尾数,必须截断。截断后存进去的值与 0.1 相差约 5.55×10⁻¹⁸。两个近似值相加,误差叠加,再转回十进制显示,就出现了 0.30000000000000004。

这类误差在任何使用双精度的语言里都存在:JavaScript、Python、Java、C 全都一样。它不是某个工具的实现问题。

为什么这个计算器显示 0.3

因为它在显示阶段才处理:计算全程用双精度完整进行,中间结果不做任何提前舍入;最后按 12 位有效数字去掉噪声,再显示。

关键在「不提前舍入」。如果每步都舍入,多步运算的误差会累积到肉眼可见;只在最后一步按有效数字收敛,既保留了计算精度,又不会把二进制噪声摊给用户看。

但要清楚:显示 0.3 不代表内部值是精确的 0.3,只是误差小于 12 位有效数字的显示精度。

什么时候不能靠这个容错

金额、库存、积分这类要求精确到分的场景,不能用浮点。正确做法是用整数分(1 元 = 100 分)或十进制类型(Java 的 BigDecimal、Python 的 decimal、Go 的 shopspring/decimal)。

判断标准很简单:如果两个结果相差 1 分钱会造成对账不平,就不能用浮点。显示层去掉噪声解决的是「看起来难受」,解决不了「账不平」。

怎么自己验证

在页面里输入 0.1+0.2,显示 0.3;再输入 0.1+0.2-0.3,显示 0(而不是 5.55e-17)——因为结果小于 12 位有效数字的精度,被收敛掉了。

想看真实的浮点结果,在浏览器控制台执行 0.1+0.2,会得到 0.30000000000000004。两者看的分别是「显示值」与「内存值」。

上面这些都不用装软件,也不用注册:打开页面就能用。

打开在线计算器 →

常见问题

为什么别的计算器显示 0.3,这个也显示 0.3,但代码里是 0.30000000000000004?

显示层做了有效数字收敛。代码里的值是真实的双精度结果,任何语言都一样;把它打印出来时各语言的默认格式化策略不同,所以看起来有的「干净」有的「脏」。

用 12 位有效数字会不会把真实的小数也截掉?

会。超过 12 位有效数字的结果会被收敛显示,比如 1/3 显示 0.333333333333(12 位)。需要更高精度请用代码里的高精度类型,页面计算器定位是日常算式。

整数运算会有这个问题吗?

在 2^53 以内不会。整数在双精度里可以精确表示,超出后同样会丢位——这也是 JSON 里超长 ID 被改值的原因。