浮点数

IEEE 754

c++浮点数类型有 float 和 double,js 的 number 采用 double 的存储方式。(这里提 c++是因为 v8 底层是 c++,其实我所知道的语言的浮点数都遵循 IEEE 754 标准,所以啥语言都一样,要是来个不遵循的反而不合直觉)

按照标准 IEEE 754 规定,浮点数的表示方法为:

(-1)^s x M x 2^E (^表示指数而不是异或,下同) 。

  • (-1)^s 表示符号位,正数 s=0,负数 s=1
  • M 是有效数字 1≤M < 2
  • E 是指数位

float 为 32 位二进制数表示,最高的 1 位是符号位 s,接着的 8 位是指数 E,剩下的 23 位为有效数字 M。1+8+23=32,double 就是 1+11+52=64,可以看到指数位和有效数字位都比 float 大了,所以整体可表示的数值也大了很多。但是规则是一样的。

接下来就说 double 的规则
double
sign 1 位比特, exponent 11 位比特, significand 52 比特.
s 表示符号位
exponent 并不是公式中的 E, 而是 E+1023(因为 E 可以为负数).
前面说过,1≤M<2,也就是说,M 可以写成 1.xxx 的形式,其中 xxx 表示小数部分 . significand 保存的就是小数部分.当 exponent 全为 1, significand 部分全为 0 时, 表示 Infinity

js 的 number 的以下几个常量说下计算方式

1
2
3
4
Number.MAX_SAFE_INTEGER === 9007199254740991;
Number.MIN_SAFE_INTEGER === -9007199254740991;
Number.MAX_VALUE === 1.7976931348623157e308;
Number.MIN_VALUE === 5e-324;

MAX_SAFE_INTEGER,最大安全整数,表示再这个范围内用于计算时不会有精度丢失。其实就是把 52 个有效数字位全部用上的最大值,2^53-1,再大一点就 M 部分就放不下了

Number.MAX_VALUE,最大数 (2^53 - 1) x 2^971
double