Показать сообщение отдельно
  #8 (permalink)  
Старый 18.10.2019, 18:03
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от Добрый_Серый_Волк
Вот, к примеру входные значения: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/

Последний раз редактировалось Malleys, 18.10.2019 в 18:31.
Ответить с цитированием