Мне нужна функция в C, которая вычисляет a^n mod q
, где делитель q определяется как очень большой (15 383 399 235 709 406 497), а показатель степени n может также быть таким же большим.
Основываясь на свойстве умножения по модулю, что (a * b) mod n = ((a mod n) * (b mod n)) mod n
, моя попытка выглядит следующим образом:
#include <stdio.h>
unsigned long long int modExp(unsigned long long int base, unsigned long long int expo, unsigned long long int mod)
{
unsigned long long int out = 1;
unsigned long long int cnt;
for (cnt=expo; cnt>0; cnt--)
{
out = (out * base) % mod;
}
return out;
}
int main()
{
printf("%llu", modExp(3, (189 + 50 * 223), 15383399235709406497));
return 0;
}
Как видно из основной функции, описанной выше, я проверил свою функцию modExp с показателем базы 3, показателем степени (189+ 50 * 223) и делитель 15383399235709406497. Он выдал вывод 3915400295876975163
с некоторыми предупреждениями о том, что
In function ‘findxA’:
findxA.c:17:32: warning: integer constant is so large that it is unsigned [enabled by default]
unsigned long long int h = 12036625823877237123;
^
findxA.c:17:5: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
unsigned long long int h = 12036625823877237123;
^
findxA.c:18:32: warning: integer constant is so large that it is unsigned [enabled by default]
unsigned long long int q = 15383399235709406497;
^
findxA.c:18:5: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
unsigned long long int q = 15383399235709406497;
^
findxA.c: In function ‘main’:
findxA.c:34:48: warning: integer constant is so large that it is unsigned [enabled by default]
printf("%llu", modExp(3, (189 + 50 * 223), 15383399235709406497));
^
findxA.c:34:5: warning: this decimal constant is unsigned only in ISO C90 [enabled by default]
printf("%llu", modExp(3, (189 + 50 * 223), 15383399235709406497));
^
Чтобы проверить этот ответ, я сравнил результат (заданный функцией C) с выводом, заданнымоценивая выражение 3^(189 + 50 * 223) `mod` 15383399235709406497
, написанное на Haskell.Это выражение Хаскелла вычисляется с другим десятичным числом, 12349118475990906085
.Я думаю, что это моя функция C, которая неправильна, так как я считаю, что Haskell лучше справляется с обработкой таких больших десятичных знаков.
Как я могу улучшить свою функцию C, modExp?
Редактировать : я попробовал вариант в качестве первого ответа на этот вопрос. Однако, поскольку я пытаюсь иметь дело с десятичной дробью без знака long long int, я переключил все типы ввода и возврата изint без знака long long int.Это привело к ошибке сегментации.
Edit2 : Я неправильно использовал описанную выше функцию.Это не дает ошибки сегментации;но он по-прежнему не выводит правильное десятичное число.