Возведение в степень
Здравствуйте!
Изучаю алгоритм RSA шифрования, и столкнулся с проблемой. Как в JS правильно возводить в трехзначную и более степень ? Например: let p = (i**e) % n;где е = 2003 и n= 4399 |
|
Math.pow() и ** при возведении в такую большую степень выбрасывают NaN, как решать подобную проблему помимо использования BigInt, который не дает делить по модулю из-за разницы типов ?
|
Цитата:
|
Если нужен только остаток, то его можно брать в ходе работы, тогда мы не упарываемся в километровые числа. Самый простой вариант - при возведении в степень n**p сделать цикл из p умножений на n (после каждого берем остаток), но гораздо быстрее смотреть биты числа р и умножать на соответствующие им значения n**(2**i)
// вычисляет (n ** p) % m function powMod(n, p, m) { if (n < 1) { return 0; } if (m < 0) { m = 0; } p = Math.round(p); n = n % m; var r = 1; while (p >= 1) { if (p % 2) { r = (r * n) % m; } n = (n * n) % m; p = Math.floor(p / 2); } return r; } alert(powMod(34546, 68883, 2437)); в хроме на относительно больших числах это работает быстрее "прямого" вычисления с BigInt |
Цитата:
function powToMod(base, power, module) { if(power === 1n) return base; if(power % 2n === 0n) return powToMod(base, power / 2n, module) ** 2n % module; return powToMod(base, power - 1n, module) * base % module; } alert(powToMod(366142356n, 1447804911n, 219020071n)); Alexandroppolus, проверьте свой алгоритм, powToMod(366142356n, 1447804911n, 219020071n) должно выдавать 38504623 Проверял также тут — https://www.wolframalpha.com/input/?...11mod219020071 |
Цитата:
function powModBig(n, p, m) { if (n < 1n) { return 0n; } if (m < 0n) { m = 0n; } n = n % m; var r = 1n; while (p >= 1n) { if (p % 2n) { r = (r * n) % m; } n = (n * n) % m; p = p / 2n; } return r; } alert(powModBig(366142356n, 1447804911n, 219020071n)) а по сути здесь абсолютно тот же алгоритм, как у тебя, только без рекурсии. ---- вариант для обычных чисел не может с такими параметрами, потому что 366142356 % 219020071 дает большое число, которое при возведении в квадрат вылезает за пределы нумбера. |
Ребят, я тут понимаю все очень серьезно, теоремы гаусса, БинИнт и прочие ругательства, но почему встроенный калькулятор не может корректно возвести в куб одну десятую и две десятых?
function fn01 (n) {return n * n * n} function fn02 (n) {return n ** 3} console.log(fn01(0.1)) console.log(fn02(0.1)) console.log(Math.pow(0.1, 3)) console.log(fn01(0.2)) console.log(fn02(0.2)) console.log(Math.pow(0.2, 3)) |
|
Часовой пояс GMT +3, время: 16:06. |