Skip to content

概述

在 javascript 中 Number 是一种定义为 64 位双精度浮点型的数字数据类型。并遵循 IEEE 二进制浮点数算术标准(IEEE754)。IEEE 754 规定了四种表示浮点数值的方式:单精确度(32 位)、双精确度(64 位)、延伸单精确度(43 比特以上,很少使用)与延伸双精确度(79 比特以上,通常以 80 位实现)。

双精度浮点数

双精度浮点数采用 64 位来存储一个浮点数。它可以表示二进位制的 53 位有效数字,其可以表示的数字的绝对值范围为 [2^-1024,2^1024]。

格式

double.jpg

  • sign bit(符号):用来表示正负号,一位,0 代表数值为正,1 代表数值为负。
  • exponent(指数):用来表示次方数,十一位,64 位双精度浮点数固定偏移为 1023.
  • mantissa(分数):用来表示精确度,五十二位。由于采用科学计数法表示是它总是以 1.x 开头的,所以在存储时只会存储小数点后 52 位,第 53 位及以后的数字不能存储,如果是 1 就向前进一位,是 0 就舍弃。

用一个公式可计算为:

(-1)^sign * 2^exponent * mantissa

64 位双精度浮点数存储的例子

0.1

  • 将 0.1 转为二进制:0.00011001100110011001100110011001100110011001100110011001(1001 无限循环)
  • 将二进制书采用科学技术法表示:2^-4 * 1.1001100110011001100110011001100110011001100110011001(1001 无限循环)
  • 从科学计数法得到各部分的值
    • sign 位:0
    • exponent 位:-4 + 1023 = 1019,再转为二进制为 01111111011
    • mantissa 位:1001100110011001100110011001100110011001100110011010(第 53 位及以后的数字不能存储,如果是 1 就向前进一位,是 0 就舍弃)
  • 最终得到的在计算机中存储的二进制数为:0 01111111011 1001100110011001100110011001100110011001100110011010

11.3

  • 将 11.3 转为二进制:1011.010011001100110011001100110011001100110011001100110011(1001 无限循环)
  • 将二进制书采用科学技术法表示:2^3 * 1.011010011001100110011001100110011001100110011001100110011(1001 无限循环)
  • 从科学计数法得到各部分的值
    • sign 位:0
    • exponent 位:3 + 1023 = 1026,再转为二进制为 10000000010
    • mantissa 位:0110100110011001100110011001100110011001100110011010(第 53 位及以后的数字不能存储,如果是 1 就向前进一位,是 0 就舍弃)
  • 最终得到的在计算机中存储的二进制数为:0 10000000010 0110100110011001100110011001100110011001100110011010

这里有一个在线测试的工具

常见问题

为什么 0.1 + 0.2 != 0.3

查看详情

计算时会首先将十进制数转为二进制再计算,由于分数位只能存储 52 位,第 53 位会发生“0 舍 1 入”,所以某些数字在转为二进制时会发生精度丢失。

为什么最大安全数字是 2^53-1 不是 2^52-1

查看详情

由于分数位只能存储 52 位,第 53 位会发生“0 舍 1 入”,所以最大的安全分数位为 52 个 1,也就是 2^53-1。

为什么 (1.335).toFixed(2) 得到的是 1.33

查看详情

1.335 先转为二进制存储在计算机中,而在转换时会发生精度丢失,实际上存储的是 1.334999999999999964472863211994990... 所以在四舍五入时得到的是 1.33。((1.335).toPrecision(52))

参考