Вы можете использовать личность, указанную вами, вам просто нужна другая аналогичная идентификация: (a+b) mod m = (a mod m) + (b mod m)
.
Цель состоит в том, чтобы умножить x*y mod m
без каких-либо промежуточных значений, превышающих предел переполнения (в данном случае 2^64), где x
начинает меньше m
(если это не так, уменьшить ее моды m
), y
возможно больше m
и x*y
может потенциально переполняться. Мы можем это сделать, если m
меньше половины предела переполнения.
Решение просто: просто выполните базовое умножение по битам для x*y
и выполните каждый шаг по модулю m
.
Начинается с x
и y
менее m
(если это не так, уменьшите его сначала). Напишите y
в форме a_0 * 2^0 + a_1 * 2^1 + a_2 * 2^2
+ ..., где a_n
либо 0, либо 1 (с указанием присутствующего термина или нет). (. Ака, написать y
в двоичной форме) Теперь мы имеем:
x * (a_0 * 2^0 + a_1 * 2^1 + a_2 * 2^2 + ...) mod m
Распределить x
по каждому из условий y
:
(x * a_0 * 2^0) + (x * a_1 * 2^1) + (x * a_2 * 2^2) + ... mod m
Затем используйте оригинальную идентичность умножения: Для каждого термина выше, умножьте x
на 2 mod m
, пока вы не достигнете желаемой мощности 2 для этого срока. (Начиная с x < m
и 2 * m < 2^64
, затем 2 * x < 2^64
, поэтому мы можем умножить на 2 без переполнения.) Когда вы закончите, добавьте результат для каждого термина mod m
(вы можете сохранить текущую сумму по ходу дела).
Ни одна из этих операций не превысит 2^64 и, следовательно, не будет переполняться. Это будет работать для любого значения m
менее 2^64/2 = 2^63 и любых целых чисел x
и y
менее m
.
Это не обязательно самый быстрый способ сделать это, не стесняйтесь находить что-то более эффективное. Во-первых, меньший m
сравнивается с лимитом переполнения, чем больше оснований для условий, которые мы можем переписать y
as.
Похоже, вам, возможно, потребуется использовать библиотеку: http://stackoverflow.com/questions/117429/handling-large-numbers-in-c, если вы не хотите, чтобы вы сами писали ее. – sircodesalot
Возможный дубликат http://stackoverflow.com/questions/14857702/specific-modular-multiplication-algorithm (который имеет принятый ответ). – halfbit
Вы сказали, что «17» в экспоненте - всего лишь пример. Вам нужно решение для этой конкретной структуры выражения или вообще для больших целых операций mod? – Nabla