Оператор JavaScript %
работает только с обычными числами JS (т. Е. IEEE 754 числа с плавающей запятой двойной точности ), но не с bigInt
объектами.Поэтому, когда вы пытаетесь применить %
к bigInt
, он сначала конвертируется в число с плавающей точкой.Если bigInt
слишком велик, чтобы его можно было точно представить с плавающей запятой двойной точности, его младшие биты будут округлены, отбрасывая любые вычисления (например, %
), которые зависят от них.
ОбщееРешение заключается в использовании метода BigInteger.js .mod()
вместо собственного оператора JavaScript %
.Однако для конкретного случая модульного возведения в степень то, что вы должны использовать, это метод .modPow()
, так как он намного более эффективен (по крайней мере для больших чисел обычноиспользуется для шифрования RSA (возможно, не для этого игрушечного примера), чем выполнить полное вычисление .pow()
и затем применить .mod()
к результату.
Вот фрагмент кода, демонстрирующий эти различные операции:
console.log('bigInt(7).pow(103) =', bigInt(7).pow(103));
console.log('bigInt(7).pow(103).mod(143) =', bigInt(7).pow(103).mod(143));
console.log('bigInt(7).modPow(103, 143) =', bigInt(7).modPow(103, 143));
console.log('Number(bigInt(7).pow(103)) =', Number(bigInt(7).pow(103)));
console.log('Number(bigInt(7).pow(103)) % 143 =', Number(bigInt(7).pow(103)) % 143);
console.log('bigInt(7).pow(103) % 143 =', bigInt(7).pow(103) % 143);
<script src="http://peterolson.github.com/BigInteger.js/BigInteger.min.js"></script>
Выполнение приведенного выше фрагмента должно привести к примерно такому выводу (возможно, с небольшими различиями форматирования в зависимости от того, какая внутренняя реализация BigInteger.js * 1033)* заканчивается использованием):
bigInt(7).pow(103) = "1109425442801291991031214184801374366124020697224286512520326098667350170655466324580343"
bigInt(7).pow(103).mod(143) = "123"
bigInt(7).modPow(103, 143) = "123"
Number(bigInt(7).pow(103)) = 1.109425442801292e+87
Number(bigInt(7).pow(103)) % 143 = 38
bigInt(7).pow(103) % 143 = 38
Ps.Недавно предложенные собственные объекты JavaScript BigInt do работают с обычными арифметическими JS-операторами, такими как %
(хотя оба операнда должны быть BigInt
с, иначе вы получите ошибку),Если ваш браузер поддерживает эту функцию, также должно работать следующее:
console.log('BigInt(7)**BigInt(103) % BigInt(143) = ' + BigInt(7)**BigInt(103) % BigInt(143) + 'n');
console.log('7n**103n % 143n = ' + 7n**103n % 143n + 'n');
В браузерах, где работает приведенный выше код, оба выражения должны иметь значение BigInt 123n
.(Очевидно, что консоль Stack Snippets еще не знает, как правильно отображать объекты BigInt, поэтому мне пришлось вручную их упорядочить, чтобы отобразить результаты.)
К сожалению, собственное предложение BigInt не позволяеткажется (пока) включают правильную модульную процедуру возведения в степень.Таким образом, для работы с модульными степенями больших чисел по-прежнему рекомендуется использовать упаковщик, такой как BigInteger.js (который должен автоматически использовать собственные BigInts, если они доступны).