返回

0.1 + 0.2 不等于 0.3?怪谁?

前端

数学世界中,0.1 + 0.2 等于 0.3 是天经地义的事。但在计算机世界里,这个简单的加法却会产生一个让人大跌眼镜的结果:0.1 + 0.2 并不等于 0.3!

这个神奇的现象背后,是计算机二进制世界的本质以及浮点数计算的奥秘。今天,我们就来一探究竟。

进制转换:从十进制到二进制

计算机内部的世界是用二进制来表示的,而我们人类习惯于使用十进制。当我们需要在计算机中存储十进制小数时,就需要进行进制转换。

以 0.1 为例,它的十进制表示可以写成:

0.1 = 1/10 = 1 * 10^(-1)

转换成二进制,我们需要不断除以 2,取余数:

0.1 = 1/10 = 0.000110011001100110011... (二进制)

由于二进制小数是小数点后只能有 0 和 1 的无理数,因此无法精确表示 0.1。计算机只能近似地将它存储为:

0.10.00011001100110011 (二进制)

这个近似值被称为浮点数

IEEE 754:浮点数的标准化

为了在不同计算机系统中实现浮点数计算的兼容性,IEEE 754 标准被广泛采用。它定义了浮点数的表示格式和运算规则。

IEEE 754 浮点数由三个部分组成:

  • 符号位: 表示数字的正负号
  • 指数位: 表示数字的阶码,即小数点的位置
  • 尾数位: 表示数字的小数部分

浮点数计算:舍入的艺术

浮点数计算涉及到一系列复杂的运算,其中舍入操作尤为关键。当浮点数进行加减乘除时,计算机往往会产生一个中间结果,这个结果通常是一个无限小数。

为了得到一个有限的表示,计算机需要对中间结果进行舍入。IEEE 754 标准定义了四种舍入方式:

  • 向最近的偶数舍入
  • 向正无穷大舍入
  • 向负无穷大舍入
  • 向 0 舍入

在默认情况下,计算机使用向最近的偶数舍入的方式。这意味着当中间结果是小数点后第 n 位时,如果第 n+1 位为偶数,则舍入到小数点后第 n 位;如果第 n+1 位为奇数,则舍入到小数点后第 n+1 位。

0.1 + 0.2 ≠ 0.3 的真相

现在,我们终于可以揭开 0.1 + 0.2 ≠ 0.3 之谜了。

当计算机执行 0.1 + 0.2 时,首先将它们转换成浮点数:

0.10.00011001100110011 (二进制)
0.20.0011001100110011 (二进制)

进行加法运算后,得到中间结果:

0.30.0100011001100110011... (二进制)

由于尾数位小数点后第 4 位为奇数,根据 IEEE 754 标准的舍入规则,应该舍入到小数点后第 5 位。因此,最终结果为:

0.30.01000110011001101 (二进制)

转换回十进制,得到:

0.30.2999999999999999888977697537484345957636833190918

这就是为什么 0.1 + 0.2 不等于 0.3 的原因。计算机的二进制表示、浮点数计算的近似性质以及舍入操作,共同造就了这一看似矛盾的现象。

结语

0.1 + 0.2 ≠ 0.3 并不是计算机的失误,而是它以二进制方式处理数字的必然结果。理解浮点数计算的原理,有助于我们更深入地了解计算机的世界,避免在编程和计算中陷入误区。