Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.2k views
in Technique[技术] by (71.8m points)

[已解决]关于JavaScript中Number整数最大长度的一个疑问

业务背景

一直以来对Number的最大最小值都没有透彻的理解清楚,在开发过程中也从来没有遇到过这种极限情况

可是最近在刷红宝书第4版的时候,又遇到这个概念.所以想透彻的搞清楚一下

关于这个概念我的理解

书上的概念

  • Number对象是采用64位存储的,即8个字节 * 8位 = 64位
  • 操作符在操作Number类型时,实际是操作的32位(位运算那一节介绍的)
  • 在底层再把32位转换成64位进行处理

我的结论

  • 最大的整数就是2的32次方减1
  • 2 ** 32 - 1
  • 书上在介绍数组索引时也能佐证,因为数组的索引是整数,最大的索引就是 2 ** 32 - 1 即4294967295

我的疑问

可是在开发过程中经常会遇到这样一个问题,JAVA侧返回的订单编号或用户ID都整型,在Web侧会出现后面2位超出JavaScript整数取值范围

如下:

java = 123456789012345678; // 一共18个数
js   = 123456789012345600; // 一共16个数外加2个0

在新的ECMAScript规范中也添加了1个Number常量最大安全整数Number.MAX_SAFE_INTEGER

  • 这个里面的最大整数和上面的一样,是16个数
  • 即2的53次方-1 2 ** 53 - 1

问题

  • 为什么Number的最大整数是2 ** 53 -1呢?

    • 如果说是64位存储的话,为什么不是2 ** 64 -1 呢.
    • 即使是去掉一个符号位,应该也是2 ** 63 -1
  • Array索引既然是整数,那它的最大索引为什么不是2 ** 53 - 1
  • 导致我有这种疑惑的根本原因在哪儿呢?

    • 是因为没有计算机基础功能?
    • 还是没有基本的逻辑思维能力?

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

前面都说的差不多了,总结下来就是 Number遵循 IEEE 754 规范:

  1. 先把Number转成二进制科学计数法表示;
  2. 然后用64位bit存储二进制科学计算法的相关参数。

64位bit分为三个部分:

  • 符号位S:第 1 位是正负数符号位(sign),0代表正数,1代表负数
  • 指数位E:中间的 11 位存储指数(exponent),用来表示次方数
  • 尾数位M:最后的 52 位是尾数(mantissa),超出的部分自动进一舍

image.png
实际数字就可以用以下公式来计算:
image.png
比如:十进制数字4.5转成二进制就是 100.1,二进制的科学计数法表示就是1.001*2^2
此时M = 1001,但是因为二进制科学计数法的尾数M的第一位固定的1,所以可以直接省去(这样可以节省一个bit,导致M最多可以表示53位),即最终M = 001

  1. 为什么Number的最大整数是2 ** 53 -1呢?
    整数需要连续性,所以表示整数时不能使用指数位E区域,只有尾数M区域可表示连续的数据,上面说了其实M最多可以表示53位。所以最大的安全整数是2 ^ 53 -1
  2. Array索引既然是整数,那它的最大索引为什么不是2 ** 53 - 1
    JS语言中数组的索引最大就是2^32 -1。就当做语言规范吧,背后的原因不清楚。除了数组索引,还有其他的地方采用32bit整数:

    • 位运算
    • setTimeout/setIntervaldelay参数也是必须是32整数
  3. 导致我有这种疑惑的根本原因在哪儿呢?

刨根问底呗。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...