Если вы попробуете 9n ** 9n ** 9n в консоли Chrome, Chrome сломается (это похоже на бесконечный цикл).Почему это происходит? - PullRequest
0 голосов
/ 28 ноября 2018

Если вы попробуете 9n**9n**9n в консоли Chrome, Chrome прекратит работу (это похоже на бесконечный цикл).

  • У двигателя V8 нет реализации для этого случая?

Я имею в виду, если вы попытаетесь 9**9**9, то вернется Infinity, что довольно мило.

  • Почему V8 не возвращает Infinity также в первом случае?
  • И почему он, похоже, входит в бесконечный цикл?

Я пробовал это и в Firefox, и этой проблемы не существует, потому что в настоящее время в SpiderMonkey нет реализации BigInt..

Спасибо!

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Как уже было сказано, 9n является представлением BigInt 9.

Оператор ** (power) работает справа налево, вызывая быструю эскалацию результатов:

2n**2n**2n === 2n ** 4n === 16n
3n**3n**3n === 3n ** 27n === 7625597484987n
4n**4n**4n === 4n ** 256n === 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096n

В моей системе это становится довольно медленным с 7n**7n**7n, что занимает около 32 секунд до вычисления печати.В результате получается 695976 цифр, первые 5000 из которых напечатаны в консоли.

Я больше не пробовал, но я бы сказал, что это просто уничтожает результат.Это может занять несколько часов или дней, чтобы вычислить отпечаток (или, возможно, в какой-то момент может возникнуть ситуация нехватки памяти).

Обновление:

Я только что попробовал var x = 7n**7n**7n в консоли Chrome, поэтому просто присвоил его переменной, и это почти мгновенно закончилось.Оказывается, преобразование бигинта в строку - это то, что отнимает время;печать x.toString().length занимает то же время, что и печать x или 7n**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

И да, этому всему есть конец:

var x = 32n**16n**8n;

дает:

VM436:1 Uncaught RangeError: Maximum BigInt size exceeded
at <anonymous>:1:28

Верхний предел в Chrome выглядит как 1 миллиард бит (1e9 бит) или около 125 МБ - ссылка: https://github.com/tc39/proposal-bigint/issues/174#issuecomment-437471065

0 голосов
/ 28 ноября 2018

Ответ о том, почему 9**9**9 возвращает бесконечность, заключается в том, что для переполнения максимального значения не требуется очень много времени (около 2 ^ 1024).Он может даже сократить его с помощью **, как если бы первое число> = 2, а второе число> 1024, тогда это будет бесконечность.

С BigInt он может представлять гораздо большие числа, поэтомуэто то, что он пытается сделать.Требуется много времени, чтобы достичь «Бесконечности» с помощью BigInt (EDIT: что на самом деле является исключением RangeError).Поиск 387420489 можно сделать довольно быстро, но 9n**387420489n, где он умножает BigInts почти 400 миллионов раз ... это занимает некоторое время.

Операция BigInt намного медленнее, чем обычная операция int.Я ожидаю, что вы можете получить результат (или исключение RangeError), если вы подождете 20-30 минут, но это может быть намного дольше.

0 голосов
/ 28 ноября 2018

Справочная информация:

В JavaScript вы можете использовать n-суффикс для создания числа в виде bigint (просто большие числа).Большие числа имеют разные способы вычислений.Обычно они более «дорогие» для вычисления.Он не использует встроенные в процессоры методы для расчетов.Вместо этого bigints используют мягкие вычисления.

Описание проблемы:

9n ** 9n означает 9 ^ 9 (9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9),Это 387420489. Даже если вы умножите 387420489 на себя, это действительно большое число.Но ** 9n означает, что вы хотите вычислить 387420489 ^ 9, что на самом деле очень большое число.Похоже, что для chrome его вычисление занимает слишком много времени или возникает какая-то неизвестная проблема.

По сути, это должна быть ошибка, о которой нужно сообщить.Странно замораживать браузер не очень удобно для пользователя.

...