maxdiver Похоже первое (точно не скажу, под руками сейчас нет), мне код понравился (там одновременно с умножением идет приведение по модулю), я даже сначала и не понял, что там скрывается. К сожалению, битность там мелкая, но я думаю, что посмотреть в любом случае стоит.
UbIvItS Хочешь побеждать - делай то, что противник ожидает меньше всего! (с) Ганнибал Поэтому не торопись с выводами, какое средство пригодится а какое нет Любой предмет по опрелению многофункционален и есть не один, а уйма способов измерять манометром высоту зданий )
Y_Mur мудрость твоя, конечно, прекрасна, но с фактами поспорить сложно) Начнём: факториал растёт быстрей чем степень - нам же нужен остаток от точного факториала, а не от его приблежённого значения, впрочем, коли ты смогешь обойти сию преграду - цены тебе не будет, ибо число сих единицы из единиц.............
UbIvItS Кто тут говорит про приближенное значение? Я еще код даже не выложил, а ты начинаешь фантазировать. И потом, какая нах разница, что в данном случае считать - степень или факториал, программу можно модифицировать.
Вот, набросал пример: Код (Text): BigNumber Factorial (BigNumber value, const BigNumber &modulus) { DWORD mu = BigNumber::PrecalcMontgomeryMU (modulus); BigNumber res, Rm1, vRm1; // Calc normalization Rm1.setBit(2*modulus.getNumChunks()*BIGNUMBER_CHUNK_BITS); Rm1.FromURemainder(Rm1,modulus); // Multiply first value res.FromUMulModMontgomery(Rm1,value,modulus,mu); value.UDecrement (1); while (value.UCmp (1)) { // convert value to montgomery form vRm1.FromUMulModMontgomery(value,Rm1,modulus,mu); // Multiply res.FromUMulModMontgomery(res,vRm1,modulus,mu); value.UDecrement (1); } // Denormalize vRm1.UAssign (1); res.FromUMulModMontgomery(res,vRm1,modulus,mu); return res; } Могу выложить скомпиленный вариант для тестов
Самописный + он в составе либы, части которой в нем используются. Может проще выложить FromUMulModMontgomery + PrecalcMontgomeryMU Остальные функции достаточно стандартные ЗЫ: Я кстати не уверен что через montgomery будет быстрее - тут 2 умножения на каждое число за счет того что надо преобразовывать их в mongomery form. Щас набросаю тестик.
Как показали полевые испытания: 65536! mod prime(2048) Mont: (4.820776 sec) 13'498'609'194 ticks Barr: (0.284845 sec) 797'594'224 ticks Вот этот код выигрывает Код (Text): BigNumber FactorialBarr (BigNumber value, const BigNumber &modulus) { BigNumber mu = BigNumber::PrecalcBarretReduction (modulus); BigNumber res (1); while (value.UCmp (1)) { // Multiply res.FromUMul (res,value); res.FromBarrettReduction (res, modulus, mu); value.UDecrement (1); } return res; } Так что montgomery multiplication ИМХО следует оставить только для montgomery exponentiation, где он рулит нипадеццки.
С английским надеюсь проблем нет Блин, что за фигня - аттачи не закачиваются. см тут: http://rapidshare.com/files/39821495/montgomery_barrett.pdf.html