如果您在Chrome的控制台中尝试9n**9n**9n,则Chrome会中断(它类似于无限循环).为什么会这样?

Tib*_*riu 10 javascript google-chrome v8 spidermonkey bigint

如果您9n**9n**9n在Chrome的控制台中尝试,Chrome会中断(它类似于无限循环).

  • V8发动机是否缺乏这种情况的实施?

我的意思是,如果你尝试9**9**9它会返回Infinity,这是一种很好的.

  • 为什么V8 Infinity在前一种情况下不会返回?
  • 为什么它似乎进入无限循环?

我也在Firefox中试过这个,这个问题不存在,因为目前SpiderMonkey中没有BigInt实现.

谢谢!

Pet*_*r B 9

正如已经说过的那样,9n是BigInt的代表9.

**(功率)运算符从右到左的作品,导致结果的快速升级:

2n**2n**2n === 2n ** 4n === 16n
3n**3n**3n === 3n ** 27n === 7625597484987n
4n**4n**4n === 4n ** 256n === 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096n
Run Code Online (Sandbox Code Playgroud)

在我的系统上,这变得非常迟缓7n**7n**7n,计算打印需要大约32秒.结果是695976位,其中前5000位在控制台中打印.

我没有再尝试过,但我会说它只是在咀嚼结果.这可能需要数小时或数天来计算打印(或者甚至可能在某些时候出现内存不足的情况).

更新:

我刚试过var x = 7n**7n**7nChrome控制台,所以只需将它分配给一个变量,这几乎没有时间完成.事实证明,将bigint转换为字符串需要花费时间; 印刷x.toString().length采用了类似的时间量作为印刷x7n**7n**7n.

进一步的实验揭示了其他有趣的行为,请看这些结果:

// Pure calculation time increases significantly when the exponent grows:
var x = 7n**7n**7n; // ~   1200 ms
var x = 7n**8n**7n; // ~   7000 ms
var x = 7n**7n**8n; // ~  62000 ms
var x = 7n**8n**8n; // ~ 470000 ms

// But it's a different story when the base number is 'simple' in binary terms, e.g. 8n:
var x = 8n**7n**7n; // ~      1 ms
var x = 8n**8n**7n; // ~      1 ms
var x = 8n**7n**8n; // ~      7 ms
var x = 8n**8n**8n; // ~     17 ms
Run Code Online (Sandbox Code Playgroud)

是的,这一切都结束了:

var x = 32n**16n**8n;
Run Code Online (Sandbox Code Playgroud)

得到:

VM436:1 Uncaught RangeError: Maximum BigInt size exceeded
at <anonymous>:1:28
Run Code Online (Sandbox Code Playgroud)

Chrome的上限似乎是10亿位(1e9位),或大约125 MB - 参考:https://github.com/tc39/proposal-bigint/issues/174#issuecomment-437471065

  • V8开发人员在这里.只是为了确认:(1)BigInts中没有"Infinity".每个操作都返回有限的BigInt或RangeError.(2)确实是`.toString`需要花费很多时间.请参阅https://github.com/tc39/proposal-bigint/issues/166.如果你真的需要一个大BigInt的文本表示,请尝试`.toString(16)`. (2认同)