Я знаю, что вам больше не нужно это, и есть альтернативное решение, но я хочу добавить альтернативный метод его реализации. Он предоставляет два разных метода: double and add algorithm и способ обработки mod(a + b, n)
с обнаружением переполнения.
Двойной алгоритм добавления обычно используется в полях, где умножение невозможно или слишком дорого рассчитывается непосредственно (например, эллиптические кривые), но мы можем принять его, чтобы обработать его в нашей ситуации, чтобы обрабатывать переполнения вместо этого.
Следующий код, вероятно, медленнее, чем принятое решение (даже при его оптимизации), но если скорость не является критичной, вы можете предпочесть ее для ясности.
unsigned addmod(unsigned x, unsigned y, unsigned n)
{
// Precondition: x<n, y<n
// If it will overflow, use alternative calculation
if (x + y <= x) x = x - (n - y);
else x = (x + y) % n;
return x;
}
unsigned sqrmod(unsigned a, unsigned n)
{
unsigned b;
unsigned sum = 0;
// Make sure original number is less than n
a = a % n;
// Use double and add algorithm to calculate a*a mod n
for (b = a; b != 0; b >>= 1) {
if (b & 1) {
sum = addmod(sum, a, n);
}
a = addmod(a, a, n);
}
return sum;
}
Примеры значений пожалуйста. –
Можете ли вы использовать библиотеку большого числа? –
Я попытался установить BigInteger, GMP и т. Д., Но я использую Windows, и для этих библиотек, похоже, требуется миллиард шагов, которые мне не удается в разные моменты, когда я сканирую список необходимых зависимостей. – WhatsInAName