Сообщение от Добрый_Серый_Волк
|
Вот, к примеру входные значения:366142356 1447804911 219020071
(вероятно)Правильный ответ - 38504623
|
Действительно правильный!
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));
BigInt не является частью спецификации ECMASCRIPT 2019, черновик смотрите на https://tc39.es/proposal-bigint/ Данный ответ написан с использованием данного черновика, возможно кардинальное изменение в логике. Не стоит сейчас это использовать в браузере, но думаю вы можете использовать в node.js, поскольку управляемое вами окружение!
https://caniuse.com/#feat=bigint
Сообщение от Aetae
|
бесит что нельзя смешивать BigInt и Number - это против всей парадигмы языка идёт
|
А как такое смешение должно работать? Например, поделим 5 на 2n. Какой результат должен получиться?
2.5 или 2n или NaN, как вы предлагаете? На самом деле математическое значение 2.5.
Семантика всех операторов в идеале должна основываться на некоторых математических принципах, чтобы соответствовать ожиданиям разработчиков. Операторы деления и нахождения остатка основаны на соглашениях из других языков программирования для целых чисел.
Тип Number может представить только математические значения c точностью в 15—17 десятичных цифр и масштабы в диапазоне примерно от 10⁻³⁰⁸ до 10³⁰⁸. Т. е. он представляет конечное число чисел. Это конечное множество чисел.
Тип BigInt представляет целочисленные математические значения. Т. е. этот тип представляет бесконечное число чисел. Это множество целых чисел.
Т. е.
получается, что тип BigInt в основном представляет бесконечное кол-во чисел, которые не могут быть выражены через тип Number.
Сообщение от Aetae
|
или, если так принципиально - NaN
|
Определённо не NaN, поскольку результатом является математическое значение 2.5.
Сообщение от Aetae
|
Возвращали бы BigInt в итоге
|
Лучше всего в данном случае выкинуть исключение о неправильных типах, поскольку и тип Number содержит числа, не приводимые к типу BigInt, и тип BigInt содержит числа, не приводимые к типу Number.
Сообщение от Aetae
|
можно было любые операции к чему угодно применять не боясь словить Exception
|
try {
alert("Symbol: " + Symbol.iterator);
} catch(error) {
alert("Это не ECMAScript1, приведите к нужному типу");
}
Однако поймали!
В ECMAScript1 не было блока try-catch, так что вы бы не смогли поймать исключение при умножении
{} * {}, поэтому вам выдают до сих пор (из-за обратной совместимости) NaN в таких случаях. Кстати при сложении строк и массивов определённой длины тоже может произойти исключение.
Продемонстрирую на примере массива
try {
const a = new Array(2 ** 32 - 1);
const b = [1, 2, 3];
const c = a.concat(b);
alert(c.length);
} catch(error) {
alert("Не складывается");
}
UPD
Так как тогда 5 поделить на 2? Используйте либо тип Number, либо тип BigInt.
alert(5n / 2n);
alert(5 / 2);
UPD
#funfact Двоичное, восьмеричное и шестнадцатеричное представление целых чисел...
alert(0xffffffffffffffffffffffffffffffffffffffffffn);
alert(0b111111111111111111111111111111111111111111n);
alert(0o777777777777777777777777777777777777777777n);
UPD
Возможно многие вопросы отпадут, если вы подумаете, что тип называется именно BigInt, а не BigDecimal.
UPD BigInt не является частью спецификации, черновик предложения
https://tc39.es/proposal-bigint/