返回

0.1 + 0.2 ≠ 0.3: IEEE 754 数值类型构造背后的秘密

前端

前言

编程世界中,常数和变量就像舞台上不可或缺的演员,它们的值决定着程序的走向。而对于数字类型而言,这些演员的构成方式至关重要,因为它影响着它们如何存储和处理数字。本文将深入探讨 IEEE 754 数值类型的内在构造,揭秘为什么在 JavaScript 中 0.1 + 0.2 ≠ 0.3 的惊人真相。

IEEE 754:数字表示的标准

IEEE 754 是一个定义浮点数表示和算术运算的国际标准。浮点数是一种近似表示实数的方法,广泛用于计算机系统中。IEEE 754 标准规范了浮点数的存储格式和运算规则,确保了不同平台和编程语言之间的一致性。

IEEE 754 数值类型构造

IEEE 754 浮点数由三个主要部分组成:符号位、指数和尾数。符号位表示数字的正负性,指数表示数字的大小,而尾数表示小数部分。

例如,十进制数 0.5 在 IEEE 754 单精度浮点数中表示为:

0 | 10000000 | 1000000000000000000000000000000000000000000000000000000000000

其中:

  • 符号位:0 表示正数
  • 指数:10000000 表示 2 的 7 次方,即 128
  • 尾数:1000000000000000000000000000000000000000000000000000000000000 表示 0.5

IEEE 754 运算的陷阱

虽然 IEEE 754 提供了浮点数表示和运算的标准,但它也带来了一些运算陷阱。其中一个陷阱就是精度损失,它发生在对有限精度表示的数字进行运算时。

0.1 和 0.2 在 IEEE 754 单精度浮点数中的精确表示如下:

0.1: 0 | 01111111 | 00110011001100110011001100110011001100110011001100110100
0.2: 0 | 01111111 | 00110011001100110011001100110011001100110011001101000000

当对这些数字进行加法运算时,尾数被截断为 23 位,导致结果精度损失:

0.1 + 0.2: 0 | 01111111 | 00110011001100110011001100110011001100110011001101000100

这个截断后的结果对应于十进制数 0.30000001192092896,而不是精确的 0.3。因此,在 JavaScript 中,0.1 + 0.2 ≠ 0.3,而是等于 0.30000001192092896。

如何避免精度陷阱

要避免精度陷阱,有几个策略可以遵循:

  • 使用十进制类型 :十进制类型提供更高的精度,但在性能方面可能会有所牺牲。
  • 进行舍入运算 :通过应用舍入规则,可以提高浮点数运算的精度。
  • 使用大数库 :大数库提供了处理高精度数字的专门功能。