Javascript跟Java等不同,对于数字没有区分类型,只有一种Number类型,即64位固定长度表示,也就是双精度浮点数。

用科学计数法来表示。
符号位S
第 1 位是正负数符号位(sign),0代表正数,1代表负数
指数位E
中间的 11 位存储指数(exponent),用来表示次方数,E是一个无符号整数,因为长度是11位,取值范围是0~2047。但是科学计数法中的指数是可以为负数的,所以再减去一个中间数 1023,[0,1022]表示为负,[1024,2047] 表示为正。此处没有使用符号位来区分指数的正负而是用范围来表示,等同于原本是可以存储11位,现在只能存储10位
尾数位M
最后的 52 位是尾数(mantissa),超出的部分自动进一舍零。但是其实尾数最大的表示数是2^53 因为尾数在二进制中第一位不为0,所以省略这一位,可以多展示一位,但是指数位最大也就是52位,即尾数位右移52位,所以当超过最大整数9007199254740992的时候,+1 还是等于9007199254740992,+2才等于9007199254740994。
最大安全整数
能够安全使用,进行算数运算的范围
2^53+1的存储和2^53一样。这样就不再“一一对应”,所以就不是安全整数。所以最大安全整数是2^53。
2^53:
符号位:0 指数:53 尾数:1.000000...000 (小数点后一共52个0)
2^53+1:
符号位:0 指数:53 尾数:1.000000...000(小数点后一共52个0),原本加1是1.000000...0001 (小数点后一共52个0,1个1,但是只能存52位,所以1没有存储,就会出现误差)。
所以能够精准表示的最大整数是 2^53 = 9007199254740992 指数位是53 尾数位是52个0 即尾数位右移53位得到9007199254740992。
但是9007199254740992+1 就会得到不准确的值。
浮点数
在十进制中会存在例如圆周率、无理数之类的小数,无法用有限的位数表示,就会进行四舍五入,也会造成不够精准,在二进制中也存在类似的数,在进行二进制表达的时候无法精准表达。
例如:
0.1 >> 0.0001 1001 1001 1001…(1001无限循环)
0.2 >> 0.0011 0011 0011 0011…(0011无限循环)
那么对于 (2^53, 2^63) 之间的数会出现什么情况呢?
(2^53, 2^54) 之间的数会两个选一个,只能精确表示偶数 (2^54, 2^55) 之间的数会四个选一个,只能精确表示4个倍数 ... 依次跳过更多2的倍数
toPrecision vs toFixed
toPrecision 是处理精度,精度是从左至右第一个不为0的数开始数起。
toFixed 是小数点后指定位数取整,从小数点开始数起。