#c_sharp
Как вычислить данное выражение не словив переполнение при Pow ? ulong Pow(ulong a, ulong b) { ulong p = 1; for (ulong i = 0; i < b; ++i) p *= a; return p; } ulong m = Pow(a, b) % c;
Ответы
Ответ 1
Если a * c не вылезает за ulong, то так: ulong Pow(ulong a, ulong b) { a = a % c; ulong p = 1; for (ulong i = 0; i < b; ++i) p = (p * a) % c; return p; } Инвариант: p < c. При умножении p * a < c * a, и по условию переполнения не происходит. Обновление: для больших значений степени имеет смысл умножать путём последовательного возведения в квадрат. ulong Pow(ulong a, ulong b) { a = a % c; ulong p = 1; ulong r = 1; while (b > 0) { if (b % 2 != 0) r = (r * p) % c; b = b / 2; p = (p * a) % c; } return r; }Ответ 2
Алгоритм Монтгомери позволяет это делать https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%9C%D0%BE%D0%BD%D1%82%D0%B3%D0%BE%D0%BC%D0%B5%D1%80%D0%B8
Комментариев нет:
Отправить комментарий