一个数字可以在不损失精度的情况下达到 JavaScript 的最高整数值是多少?

What is JavaScript's highest integer value that a number can go to without losing precision?

提问人:TALlama 提问时间:11/21/2008 最后编辑:Peter MortensenTALlama 更新时间:3/2/2022 访问量:661593

问:

这是由语言定义的吗?是否有定义的最大值?在不同的浏览器中会有所不同吗?

JavaScript 数学 跨浏览器

评论

6赞 Dmitri Zaitsev 5/18/2016
对于像 github.com/MikeMcl/big.js 这样的库,你不需要依赖 JS 的限制,例如,参见 这里 了解它的可靠性测试
4赞 George 3/27/2018
您可以与 Big.js 一起使用的最高整数值是多少?
1赞 Amadan 1/6/2020
@DmitriZaitsev 我们不再需要依赖外部库(至少在某些浏览器上)。 是一个非常非常大的整数,不会损失任何精度,不需要任何依赖关系(不用说,甚至没有接近限制)。1n << 10000n
1赞 Amadan 1/8/2020
@DmitriZaitsev 注意后缀。 class 是 ES2020 规范草案的一部分,已经在大多数浏览器中实现;您可以尝试在没有外部库的情况下在 Chrome 或 Firefox 中对其进行评估,并获得 3011 位 .nBigIntBigInt
2赞 Amadan 1/8/2020
@DmitriZaitsev:是的,它仅适用于整数。这个问题是关于整数的。

答:

496赞 Peter Bailey 11/21/2008 #1

>= ES6:

Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;

<= ES5

参考资料:

Number.MAX_VALUE;
Number.MIN_VALUE;

console.log('MIN_VALUE', Number.MIN_VALUE);
console.log('MAX_VALUE', Number.MAX_VALUE);

console.log('MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER); //ES6
console.log('MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER); //ES6

评论

23赞 TALlama 11/21/2008
我已经编辑了这个问题,以便更精确地想要最大整数值,而不仅仅是最大数字值。很抱歉造成混乱,在这里。
5赞 Pacerier 9/22/2013
是否保证返回的结果在所有浏览器上都相同?
7赞 Michael Scheper 6/11/2014
请注意,这是最小的可能正数。最小值(即小于其他任何值)可能是 。Number.MIN_VALUE-Number.MAX_VALUE
2赞 Teepeemm 7/23/2014
这是最大浮点值。问题是关于最高整数值的。虽然是一个整数,但你不能在不失去精度的情况下过去。Number.MAX_VALUE2^53
37赞 superlukas 8/31/2014
ES6 引入了Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER
980赞 Jimmy 11/21/2008 #2

JavaScript 有两种数字类型:NumberBigInt

最常用的数字类型是 64 位浮点 IEEE 754 数字。Number

此类型的最大精确整数值是 Number.MAX_SAFE_INTEGER,即:

  • 253-1,或
  • +/- 9,007,199,254,740,991,或
  • 九万亿 七万亿 一百九十九亿 二百五十四百万 七十四万 九百九十一

从这个角度来看:一千万亿字节是 PB(或一千 TB)。

在这种情况下,“安全”是指准确表示整数并正确比较它们的能力。

从规格:

请注意,所有大小为 no 的正整数和负整数 大于 253 在类型中可表示(实际上, 整数 0 有两种表示形式,+0 和 -0)。Number

为了安全地使用大于此值的整数,您需要使用 BigInt,它没有上限。

请注意,按位运算符和移位运算符对 32 位整数进行运算,因此在这种情况下,最大安全整数为 231-1,即 2,147,483,647。

const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !

// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2)      // 4503599627370496
log(x >> 1)     // 0
log(x | 1)      // 1


关于数字 9,007,199,254,740,992 主题的技术说明:此值有一个精确的 IEEE-754 表示形式,您可以从变量中分配和读取此值,因此对于小于或等于此值的整数域中非常仔细选择的应用程序,您可以将其视为最大值。

在一般情况下,必须将此 IEEE-754 值视为不准确,因为它编码的逻辑值是 9,007,199,254,740,992 还是 9,007,199,254,740,993 是不明确的。

评论

77赞 TALlama 11/21/2008
这似乎是对的,但是有没有定义它的地方,比如 C 的 MAX_INT 或 Java 的 Integer.MAX_VALUE?
53赞 coolaj86 8/24/2011
4294967295 === Math.pow(2,32) - 1;
13赞 Pacerier 10/16/2011
那么,我们可以用什么最小和最大的整数来确保精确的精度呢?
41赞 Beetroot-Beetroot 8/31/2012
也许值得注意的是,javascript 中没有实际的 (int)。Number 的每个实例都是 (float) 或 NaN。
60赞 Willem D'Haeseleer 8/22/2014
9007199254740992并不是真正的最大值,这里的最后一位已经假设为零,所以你失去了 1 位精度。真正的安全数字是 9007199254740991 ( Number.MAX_SAFE_INTEGER )
-7赞 jishi 11/21/2008 #3

Firefox 3 似乎对大量数字没有问题。

1e+200 * 1e+100 将计算为 1e+300。

Safari似乎也没有问题。(郑重声明,如果其他人决定测试这一点,这是在 Mac 上。

除非我在一天中的这个时候失去了大脑,否则这比 64 位整数要大得多。

评论

18赞 Jimmy 11/22/2008
它不是 64 位整数,而是一个 64 位浮点数,其中 52/53 位是整数部分。因此,它可以处理高达 1e300,但不能精确地处理。
4赞 Ryan 10/8/2011
吉米是对的。在浏览器或 JS 命令行中尝试以下操作:100000000000000010 - 1 => 100000000000000020
4赞 Raynet 11/21/2008 #4

我用公式 X-(X+1)=-1 做了一个简单的测试,我可以在 Safari、Opera 和 Firefox(在 OS X 上测试)上获得的最大 X 值是 9e15。这是我用于测试的代码:

javascript: alert(9e15-(9e15+1));

评论

1赞 Wedge 11/21/2008
请注意,9e15 = 2^53(参见@Jimmy的答案)。
6赞 devios1 9/20/2012
9e15 = 9000000000000000。2^53 = 9007199254740992。因此,为了迂腐,9e15 仅近似等于 2^53(有两个有效数字)。
0赞 Royi Namir 11/13/2013
@chaiguy 其中有 1 个有效数字。在“9007199254740992”中,有 15 个有效数字。9000000000000000
0赞 devios1 11/14/2013
@RoyiNamir 不想在这里开始毫无意义的争论,但 900000000000000000 有 16 位有效数字。如果你只想要 1,它必须写成 9x10^15。
1赞 Royi Namir 11/14/2013
@chaiguy号 原样 - 有 SF。 哪里有 2。(sigfigscalculator.appspot.com) & mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (底部)9000000000000000190*10^14
7赞 Martin Naatz 6/20/2010 #5

尝试:

maxInt = -1 >>> 1

在 Firefox 3.6 中,它是 2^31 - 1。

评论

2赞 kumarharsh 12/24/2013
@danorton:我不确定你是否明白你在做什么。意味着提升到权力。在 javascript 控制台中,是 XOR,而不是^^
2赞 kumarharsh 12/25/2013
打开 Chrome/Firefox 控制台。键入 5^2。在二进制中,5 是,2 是 。现在,如果你对它们进行按位异或,你会得到 如果你感到困惑,请阅读这篇文章 这里讨论的不是运算符1010105(101) ^ 2(010) = 7(111)Math.pow()^
3赞 danorton 1/1/2014
同样,我一点也不困惑。我已经对所写的内容进行了评论和反对。如果Math.pow()是这个意思,那么这就是应该写的。在回答有关 JavaScript 的问题时,使用其他语言的语法是不合适的。使用在 JavaScript 中有效的语法,但在 JavaScript 中具有与预期不同含义的解释更不合适。
11赞 lmm 3/5/2014
2^31 是英语中 2 的 31 次方的写法。它不在代码块中。你会抱怨有人使用 ;在答案中,因为这是一个在 Javascript 中具有不同含义的字符?
3赞 jocke-l 6/3/2015
尽管应该用纯文本写 2³¹ 而不是 2^31,但这样做很常见,因为大多数键盘布局默认没有这些字符。至少我理解这个答案的意思没有任何问题。
119赞 Vjeux 12/7/2010 #6

它是 253 == 9 007 199 254 740 992。这是因为 s 以浮点形式存储在 52 位尾数中。Number

最小值为 -253

这使得一些有趣的事情发生

Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true

也可能是危险的:)

var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
    // infinite loop
}

延伸阅读:http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html

评论

1赞 ninjagecko 7/9/2015
尽管人们永远不会在理智的时间范围内到达 for 循环的终点,但您可能希望说i += 1000000000
4赞 Ted Bigham 1/5/2016
@ninjagecko,他从MAX_INT开始,所以终点就在那里。此外,使用 i+= 1000000000 将使它不再是无限循环。试试吧。
0赞 ninjagecko 1/5/2016
@TedBigham:哎呀,准备得太快了。谢谢你纠正我两次。
1赞 T.J. Crowder 9/30/2018
请参阅吉米对 9,007,199,254,740,991 而不是 9,007,199,254,740,992 的论点。这与我的后续行动相结合,似乎很有说服力。
31赞 danorton 7/17/2011 #7

简短的回答是“视情况而定”。

如果在任何地方使用按位运算符(或者引用的是 Array 的长度),则范围为:

无符号:0…(-1>>>0)

签署:(-(-1>>>1)-1)…(-1>>>1)

(碰巧的是,按位运算符和数组的最大长度限制为 32 位整数。

如果不使用按位运算符或使用数组长度:

签署:(-Math.pow(2,53))…(+Math.pow(2,53))

这些限制是由“数字”类型的内部表示施加的,该表示形式通常对应于 IEEE 754 双精度浮点表示。(请注意,与典型的有符号整数不同,负限的大小与正限的大小相同,这是由于内部表示的特征,实际上包括 0!

评论

0赞 Charlie Affumigato 11/24/2013
这是我想偶然发现的关于如何将 X 转换为 32 位整数或无符号整数的答案。为此,您的答案投了赞成票。
34赞 coolaj86 8/25/2011 #8

为了安全起见

var MAX_INT = 4294967295;

推理

我以为我会很聪明,用更务实的方法找到价值。x + 1 === x

我的机器每秒只能数 1000 万左右......所以我会在 28.56 年后发回明确的答案。

如果你等不了那么久,我敢打赌

  • 您的大多数循环不会运行 28.56 年
  • 9007199254740992 === Math.pow(2, 53) + 1足以证明
  • 您应该坚持这样做,以避免位移的预期问题4294967295Math.pow(2,32) - 1

发现:x + 1 === x

(function () {
  "use strict";

  var x = 0
    , start = new Date().valueOf()
    ;

  while (x + 1 != x) {
    if (!(x % 10000000)) {
      console.log(x);
    }

    x += 1
  }

  console.log(x, new Date().valueOf() - start);
}());

评论

5赞 MickLH 11/18/2013
你不能从 2^53 - 2 开始测试吗?(是的,你可以,我刚刚试过了,即使使用 -3 以确保安全:var x=Math.pow(2,53)-3;而 (x!=x+1) x++;)-> 9007199254740991
1赞 higuaro 3/4/2014
不错的答案!此外,我知道该值已结算,但为什么不使用二进制搜索来查找它呢?
1赞 coolaj86 3/5/2014
这有什么好玩的?此外,@Briguy37打败了我:stackoverflow.com/a/11639621/151312
0赞 Jerry 5/21/2014
请注意,与 Date 值相比,这种基于 32 位的“安全”MAX_INT将不起作用。4294967295昨天!
1赞 coolaj86 12/28/2014
答案“为了安全起见:var MAX_INT = 4294967295;”并不幽默。如果你没有位移,不要担心它(除非你需要一个大于 4294967295 的 int,在这种情况下,你可能应该将其存储为字符串并使用 bigint 库)。
-1赞 Tommy 1/10/2012 #9

在 Google Chrome 内置的 javascript 中,您可以在该数字称为无穷大之前转到大约 2^1024。

评论

0赞 jkdev 2/10/2015
Math.pow(基数,指数)
65赞 BananaNeil 1/21/2012 #10

在 JavaScript 中,有一个数字称为 .Infinity

例子:

(Infinity>100)
=> true

// Also worth noting
Infinity - 1 == Infinity
=> true

Math.pow(2,1024) === Infinity
=> true

对于有关此主题的一些问题,这可能就足够了。

评论

27赞 devios1 9/20/2012
有人告诉我,无穷大不符合整数的条件。:)
8赞 djjeck 10/24/2012
但是,当您查找最小值时,初始化变量就足够了。min
9赞 H.Wolper 10/18/2013
请注意,Infinity - 1 === Infinity
2赞 Sijav 10/30/2013
also (Infinity<100) => false 和 Math.pow(2,1024) === 无穷大
6赞 dmccabe 11/6/2014
同样值得一提的是,它确实也处理了负无限。所以1 - Infinity === -Infinity
9赞 Scato 5/15/2012 #11

要用于按位运算的任何内容都必须介于 0x80000000(-2147483648 或 -2^31)和 0x7fffffff(2147483647 或 2^31 - 1)之间。

控制台会告诉你 0x80000000 等于 +2147483648,但 0x80000000 & 0x80000000 等于 -2147483648。

41赞 Briguy37 7/25/2012 #12

Jimmy 的答案正确地将连续的 JavaScript 整数谱表示为 -9007199254740992 以9007199254740992包容性(对不起,9007199254740993,你可能认为你9007199254740993,但你错了!下面或在 jsfiddle 中演示)。

console.log(9007199254740993);

然而,没有答案可以以编程方式找到/证明这一点(除了 CoolAJ86 在他的答案中提到的将在 28.56 年;)完成的答案,所以这里有一个稍微更有效的方法(准确地说,它在大约 28.559999999968312 年:)更有效,还有一个测试小提琴

/**
 * Checks if adding/subtracting one to/from a number yields the correct result.
 *
 * @param number The number to test
 * @return true if you can add/subtract 1, false otherwise.
 */
var canAddSubtractOneFromNumber = function(number) {
    var numMinusOne = number - 1;
    var numPlusOne = number + 1;
    
    return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}

//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher

//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
    highestNumber *= 2;
}

//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
    while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
        highestNumber = highestNumber - numToSubtract;
    }
    
    numToSubtract /= 2;
}        

//And there was much rejoicing.  Yay.    
console.log('HighestNumber = ' + highestNumber);

评论

8赞 Briguy37 2/13/2013
@CoolAJ86:哈哈,我很期待2040年3月15日。如果我们的数字匹配,我们应该举办派对:)
0赞 MickLH 11/18/2013
var x=数学.pow(2,53)-3;而 (x!=x+1) x++;-> 9007199254740991
0赞 Briguy37 11/18/2013
@MickLH:我9007199254740992了那个代码。您使用什么 JavaScript 引擎进行测试?
0赞 MickLH 11/19/2013
你用自己的代码得到9007199254740992,我没有使用 x 的最终值,而是出于偏执的原因使用 x++ 的最终抽真空。顺便说一句,谷歌浏览器。
0赞 peterflynn 11/24/2013
@MickLH:在增量发生之前,评估会给出 x 的值,因此这可能解释了这种差异。如果希望表达式的计算结果与 x 的最终值相同,则应将其更改为 。x++++x
-7赞 TinyTimZamboni 3/22/2013 #13

Node.js 和 Google Chrome 似乎都使用 1024 位浮点值,因此:

Number.MAX_VALUE = 1.7976931348623157e+308

评论

1赞 Roy Tinker 4/4/2013
-1:最大可表示(非精确整数)数可能是 ~2^1024,但这并不意味着它们偏离了 IEEE-754 64 位标准。
2赞 Raul Guiu 5/29/2013
MAX_INT?你是说MAX_VALUE吗?
3赞 phuclv 8/4/2013
这是浮点值的最大值。这并不意味着你可以存储一个 int 那么长
1赞 IMSoP 6/17/2014
或者更确切地说,你无法在不损失准确性的情况下可靠地存储 int 那么长时间。 之所以被称为,是因为在该点之上,值成为近似值,就像分数一样。2^53MAX_SAFE_INT
13赞 Philippe97 10/6/2013 #14

其他人可能已经给出了通用答案,但我认为给出一种快速确定它的方法是个好主意:

for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);

这让我在 Chrome 30 中不到一毫秒的时间内9007199254740992。

它将测试 2 的幂,以找出哪一个,当“添加”1 时,等于他自己。

评论

0赞 Sapphire_Brick 11/14/2019
它可能会使您的应用程序崩溃,想。
29赞 WaiKit Kung 3/31/2014 #15

ECMAScript 6:

Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;

评论

1赞 cregox 5/7/2015
请注意,并非所有浏览器都支持此功能!今天,iOS(甚至不是 chrome)、Safari 和 IE 都不喜欢它。
6赞 WaiKit Kung 5/8/2015
请仔细阅读答案,我们没有使用 ECMAScript 6 中 Number.MAX_SAFE_INTEGER 的默认实现,我们通过 Math.pow(2, 53)-1 来定义它
0赞 cregox 5/8/2015
我以为它只是对如何在 ECMA 6 中实现它的参考!:P不过,我认为我的评论仍然有效。一切都是上下文问题。;)
3赞 kjv 5/27/2015
在所有浏览器中通过向后计算是否可靠?你应该继续前进吗?即,Number.MAX_SAFE_INTEGER = 2 * (Math.pow(2, 52) - 1) + 1;MAX_SAFE_INTEGER
0赞 ioquatix 3/13/2017
操作安全吗?它比最大的安全整数大一个。Math.pow(2, 53)-1
3赞 jerome 9/25/2014 #16

我是这样写的:

var max_int = 0x20000000000000;
var min_int = -0x20000000000000;
(max_int + 1) === 0x20000000000000;  //true
(max_int - 1) < 0x20000000000000;    //true

int32 相同

var max_int32 =  0x80000000;
var min_int32 = -0x80000000;
-2赞 SammieFox 12/25/2016 #17

斯卡托写道:

要用于按位运算的任何内容都必须介于 0x80000000(-2147483648 或 -2^31)和0x7fffffff(2147483647 或 2^31 - 1).

控制台会告诉您 0x80000000 等于 +2147483648,但是 0x80000000 & 0x80000000 等于 -2147483648

十六进制小数是无符号正值,所以 0x80000000 = 2147483648 - 这在数学上是正确的。如果要使它成为有符号值,则必须右移:0x80000000 >> 0 = -2147483648。您也可以改写 1 << 31。

47赞 Carr 3/11/2018 #18

许多早期的答案都表明是正确的,以验证 9,007,199,254,740,991 是最大和安全的整数。9007199254740992 === 9007199254740992 + 1

但是,如果我们继续做积累呢?

input: 9007199254740992 + 1  output: 9007199254740992  // expected: 9007199254740993
input: 9007199254740992 + 2  output: 9007199254740994  // expected: 9007199254740994
input: 9007199254740992 + 3  output: 9007199254740996  // expected: 9007199254740995
input: 9007199254740992 + 4  output: 9007199254740996  // expected: 9007199254740996

我们可以看到,在大于 9,007,199,254,740,992 的数字中,只有偶数是可表示的。

这是一个解释双精度 64 位二进制格式如何工作的条目。让我们看看如何使用这种二进制格式来保存(表示)9,007,199,254,740,992

使用一个简短的版本来演示它 4,503,599,627,370,496

  1 . 0000 ---- 0000  *  2^52            =>  1  0000 ---- 0000.  
     |-- 52 bits --|    |exponent part|        |-- 52 bits --|

在箭头的左侧,我们有位值 1 和一个相邻的基点。通过消耗左侧的指数部分,基点向右移动 52 步。基数点在末尾结束,我们得到纯二进制4503599627370496。

现在让我们继续用 1 递增分数部分,直到所有位都设置为 1,这等于十进制的 9,007,199,254,740,991

  1 . 0000 ---- 0000  *  2^52  =>  1  0000 ---- 0000.  
                       (+1)
  1 . 0000 ---- 0001  *  2^52  =>  1  0000 ---- 0001.  
                       (+1)
  1 . 0000 ---- 0010  *  2^52  =>  1  0000 ---- 0010.  
                       (+1)
                        . 
                        .
                        .
  1 . 1111 ---- 1111  *  2^52  =>  1  1111 ---- 1111. 

由于 64 位双精度格式严格地为分数部分分配 52 位,因此如果我们再添加 1,则没有更多位可用,因此我们可以做的是将所有位设置回 0,并操作指数部分:

  ┏━━▶ This bit is implicit and persistent.
  ┃        
  1 . 1111 ---- 1111  *  2^52      =>  1  1111 ---- 1111. 
     |-- 52 bits --|                     |-- 52 bits --|

                          (+1)

  1 . 0000 ---- 0000  *  2^52 * 2  =>  1  0000 ---- 0000. * 2  
     |-- 52 bits --|                     |-- 52 bits --|
                                      (By consuming the 2^52, radix
                                       point has no way to go, but
                                       there is still one 2 left in
                                       exponent part)
  =>  1 . 0000 ---- 0000  *  2^53 
         |-- 52 bits --| 

现在我们得到 9,007,199,254,740,992,对于大于它的数字,格式只能处理 2 的增量,因为分数部分的每个增量 1 最终都会乘以指数部分的左边 2。这就是为什么双精度 64 位二进制格式在数字大于 9,007,199,254,740,992 时不能保存奇数的原因:

                            (consume 2^52 to move radix point to the end)
  1 . 0000 ---- 0001  *  2^53  =>  1  0000 ---- 0001.  *  2
     |-- 52 bits --|                 |-- 52 bits --|

按照这种模式,当数字大于 9,007,199,254,740,992 * 2 = 18,014,398,509,481,984 时,只能保持分数的 4 倍:

input: 18014398509481984 + 1  output: 18014398509481984  // expected: 18014398509481985
input: 18014398509481984 + 2  output: 18014398509481984  // expected: 18014398509481986
input: 18014398509481984 + 3  output: 18014398509481984  // expected: 18014398509481987
input: 18014398509481984 + 4  output: 18014398509481988  // expected: 18014398509481988

[ 2 251 799 813 685 2484 503 599 627 370 496 之间的数字怎么样?

 1 . 0000 ---- 0001  *  2^51  =>  1 0000 ---- 000.1
     |-- 52 bits --|                |-- 52 bits  --|

二进制中的值 0.1 正好是 2^-1 (=1/2) (=0.5) 因此,当数字小于 4,503,599,627,370,496 (2^52) 时,有一个位可用于表示整数的 1/2 倍

input: 4503599627370495.5   output: 4503599627370495.5  
input: 4503599627370495.75  output: 4503599627370495.5  
            

小于 2,251,799,813,685,248 (2^51

input: 2251799813685246.75   output: 2251799813685246.8  // expected: 2251799813685246.75 
input: 2251799813685246.25   output: 2251799813685246.2  // expected: 2251799813685246.25 
input: 2251799813685246.5    output: 2251799813685246.5
/**
   Please note that if you try this yourself and, say, log 
   these numbers to the console, they will get rounded. JavaScript
   rounds if the number of digits exceed 17. The value 
   is internally held correctly:
*/
            
input: 2251799813685246.25.toString(2) 
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2) 
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)   
output: "111111111111111111111111111111111111111111111111110.11"

指数部分的可用范围是多少?格式为其分配的 11 位。

来自维基百科(有关更多详细信息,请访问此处)

IEEE 754 Double Floating Point Format.svg

因此,要使指数部分为 2^52,我们正好需要设置 e = 1075。

3赞 simhumileco 7/18/2018 #19

让我们来看看源头

描述

常量的值为 (9,007,199,254,740,991 或 ~9 千万亿)。该数字背后的原因是 JavaScript 使用 IEEE 754 中指定的双精度浮点格式数字,并且只能安全地表示介于 和 之间的数字。MAX_SAFE_INTEGER9007199254740991-(2^53 - 1)2^53 - 1

在这种情况下,安全是指准确表示整数并正确比较它们的能力。例如,将计算结果为 true,这在数学上是不正确的。有关更多信息,请参见 Number.isSafeInteger()。Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2

由于是 Number 的静态属性,因此始终将其用作 ,而不是您创建的 Number 对象的属性。MAX_SAFE_INTEGERNumber.MAX_SAFE_INTEGER

浏览器兼容性

enter image description here

1赞 Marwen Trabelsi 12/20/2018 #20

在 JavaScript 中,数字的表示形式是 。2^53 - 1

但是,按位运算是按 32 位(4 字节)计算的,这意味着如果超过 32 位移位,您将开始丢失位。

评论

1赞 JimbobTheSailor 3/8/2021
这是很重要的一点。这就是为什么我在这里谷歌搜索 max int size。其他答案建议 53 位,所以我对其进行编码,认为我可以安全地对正值进行到 52 位的位算术。但它在 31 位后失败了。谢谢@Marwen
8赞 trincot 12/28/2018 #21

JavaScript 在 ECMAScript 2020 中获得了一种新的数据类型:.它引入了具有“n”后缀的数字文字,并允许任意精度:BigInt

var a = 123456789012345678901012345678901n;

当然,当如此大的整数被强制(可能是无意的)强制转换为数字数据类型时,精度仍然会丢失。

而且,显然,由于内存有限,总是会存在精度限制,并且为了分配必要的内存和对如此大的数字执行算术运算,总会存在时间成本。

例如,生成一个具有十万位十进制数字的数字,在完成之前需要明显的延迟:

console.log(BigInt("1".padEnd(100000,"0")) + 1n)

...但它有效。