深度解析Javascript中的number内部

JavaScript中的Number类型是基于IEEE 754标准的双精度(64位)浮点数格式。

一、IEEE 754双精度格式

假设我们要表示数字-12.375

1. 符号位 (Sign bit):
对于负数,符号位为1;对于正数或0,符号位为0。
因此,对于-12.375,符号位是:1

2. 将数字转换为二进制形式:
我们首先将整数和小数部分分开。

整数部分:12的二进制表示是1100

小数部分:

  • 0.375 * 2 = 0.75 => 0
  • 0.75 * 2 = 1.5 => 1
  • 0.5 * 2 = 1.0 => 1
    所以,0.375的二进制表示是.011

将整数和小数部分组合起来,我们得到:1100.011

3. 标准化这个二进制数字:
将它写成二进制科学记数法的形式:
1100.011 = 1.100011 x 2^3

在这里,1.100011是标准化的尾数,3是指数。

4. 指数 (Exponent):
根据IEEE 754双精度格式,我们需要为实际的指数加上一个偏移量1023。
所以:3 + 1023 = 1026
1026的二进制是:10000000010。这是11位的指数部分。

5. 尾数 (Significand, Fraction, Mantissa):
在标准化的二进制形式中,尾数部分的隐式前导1可以被省略(我们已经知道它总是1,除非指数是全0)。因此,我们只需保留小数点后的部分:100011
由于尾数部分为52位,我们需要用0填充这个值,直到它有52位长度。但在此示例中,为了简单起见,我们只展示了几位。

组合所有这些部分,我们得到了-12.375在IEEE 754双精度格式中的表示:
1 10000000010 100011...

注意,这只是一个简化的表示法。在实际的IEEE 754双精度表示中,尾数部分还需要更多的0来达到52位长度。

二、Javascript中的number类型

在 JavaScript 中,number 类型基于 IEEE 754 双精度浮点数标准。这意味着每一个 JavaScript number 类型的值都是由以下三个部分组成的:

  1. 符号位 (1位): 这个位确定数字是正数(0)还是负数(1)。
  2. 指数 (11位): 这11个位确定了二进制小数点的位置。
  3. 尾数/有效数 (52位): 这部分表示实际数字的位,但要注意,正规范化数的前导1是隐式的。

为了进一步解释这个概念,让我们通过几个例子看一下:

  1. 整数

    让我们考虑整数 5

    二进制表示为 101,转化为浮点格式是 1.01 × 2^2

    指数是2,但在双精度中,真实存储的指数值 = 指数 + 1023 = 1025,即 10000000001

    尾数是 01,在双精度中,尾数需要52位,所以我们填充它,变成 010000... (共52位)。

    最终表示为:0 10000000001 010000...000

  2. 小数

    考虑 0.15625,其二进制表示为 0.00101,标准化后为 1.01 × 2^-3

    指数是-3,真实存储的指数值 = -3 + 1023 = 1020,即 01111111100

    尾数是 01,填充后为 010000...000

    最终表示为:0 01111111100 010000...000

  3. 特殊值

    • +Infinity: 0 11111111111 000...000
    • -Infinity: 1 11111111111 000...000
    • NaN: 任何指数为全1和非零尾数的组合,例如: 0 11111111111 100...000
  4. 非规范化数

    考虑一个非常小的值,比如 2.2250738585072014e-308,这是正规范化数的下限。更小的值就变成非规范化数,如 2^-1075

    对于非规范化数,指数为 00000000000。尾数直接表示这个值,不需要前导1。

    非规范化数实际上是指当一个数值小到指数全都为0时,尾数的含义就变了,尾数默认的前导位“1”变成了“0”。举例来说,1.01 × 2^2这个数的尾数是“01”,小数点前面的“1”就是前导位,保存到计算机中时前导位是被省略了的,指数保存到计算机中要加上1023,也就是说看到计算机里面保存的尾数为“01”,指数为“1025”,我们就知道这个数实际上是1.01 × 2^2。但当指数为0时,前导位就变成0了,也就是当我们看到计算机里面保存的尾数为“01”,指数为“0”,我们就知道这个数实际上是0.01 × 2^(-1022)而不是1.01 × 2^(-1022),注意,计算机中指数为“0”表示“-1022”(非规范化数规定),为“1”也表示“-1022”(因为1-1023=-1022)。非规范化数是为了能表示更多更小的数值。

  5. 正0: 0 00000000000 000...000

    负0: 1 00000000000 000...000

希望上面的例子有助于更好地理解在JavaScript中如何使用 IEEE 754 双精度浮点数表示 number 值。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注