# js的数值范围以及为什么

JavaScript能表示并进行精确算术运算的整数范围为:正负2的53次方,也即从最小值-9007199254740992到最大值+9007199254740992之间的范围;对于超过这个范围的整数,JavaScript依旧可以进行运算,但却不保证运算结果的精度。

+"6145390195186705543"    // 出现精度问题,6145390195186705000
BigInt("6145390195186705543" )+1n  //6145390195186705544n

JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,11.0是相同的,是同一个数。

1 === 1.0 // true

由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。

0.1 + 0.2 === 0.3
// false

//0.1 => 0.0001 1001 1001 1001…(无限循环)
//0.2 => 0.0011 0011 0011 0011…(无限循环)

//双精度浮点数的小数部分最多支持 52 位,所以两者相加之后得到这么一串 0.0100110011001100110011001100110011001100110011001100因浮点数小数位的限制而截断的二进制数字,这时候,我们再把它转换为十进制,就成了0.30000000000000004。

0.3 / 0.1
// 2.999999999999999

(0.3 - 0.2) === (0.2 - 0.1)
// false

# 数值精度

根据国际标准 IEEE 754,JavaScript 浮点数的64个二进制位,从最左边开始,是这样组成的。

  • 第1位:符号位,0表示正数,1表示负数 (1位)
  • 第2位到第12位:指数部分 (11位)
  • 第13位到第64位:尾数部分 (52位)

符号位决定了一个数的正负,指数部分决定了数值的大小,小数部分决定了数值的精度。

IEEE 754 规定,有效数字第一位默认总是1,不保存在64位浮点数之中。也就是说,有效数字总是1.xx...xx的形式,其中xx..xx的部分保存在64位浮点数之中,最长可能为52位。因此,JavaScript 提供的有效数字最长为53个二进制位。

(-1)^符号位 * 1.xx...xx * 2^指数位

精度最多只能到53个二进制位(有一位不在浮点数中),这意味着,绝对值小于253次方的整数,即-(2^53-1)2^53-1,都可以精确表示。

2^0+2^1+...+2^52 = 2^53-1 
最后更新时间: 9/3/2021, 7:07:07 PM