快速的方法来计算N!模m其中m为质数? [英] Fast way to calculate n! mod m where m is prime?

查看:174
本文介绍了快速的方法来计算N!模m其中m为质数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很好奇,如果有一个很好的办法做到这一点。我现在的code是这样的:

I was curious if there was a good way to do this. My current code is something like:

def factorialMod(n, modulus):
    ans=1
    for i in range(1,n+1):
        ans = ans * i % modulus    
    return ans % modulus

但似乎很慢!

But it seems quite slow!

我也无法计算N!然后应用数模数,因为有时n是如此之大,使得n!是明确的计算只是不可行。

I also can't calculate n! and then apply the prime modulus because sometimes n is so large that n! is just not feasible to calculate explicitly.

我也碰到<一href="http://en.wikipedia.org/wiki/Stirling%27s_approximation">http://en.wikipedia.org/wiki/Stirling%27s_approximation并想知道这是否可以被用在这里都以某种方式?

I also came across http://en.wikipedia.org/wiki/Stirling%27s_approximation and wonder if this can be used at all here in some way?

或者说,还有可能创建一个递归,memoized在C ++函数?

Or, how might I create a recursive, memoized function in C++?

推荐答案

扩大我的评论来回答:

是的,有更有效的方法来做到这一点。 但是他们都非常凌乱。

Yes, there are more efficient ways to do this. But they are extremely messy.

所以,除非你真的很需要那额外的性能,我不建议尝试实施这些。

关键是要注意的是,弹性模量(这基本上是一个部门)将是瓶颈操作。幸运的是,有一些非常快速的算法,使您可以进行模数较上年数多次。

The key is to note that the modulus (which is essentially a division) is going to be the bottleneck operation. Fortunately, there are some very fast algorithms that allow you to perform modulus over the same number many times.

  • Division by Invariant Integers using Multiplication
  • Montgomery Reduction

这些方法是快速的,因为他们从根本上杜绝模量。

These methods are fast because they essentially eliminate the modulus.

独这些方法应该给你一个温和加速。要真正有效,您可能需要展开循环,以便更好地IPC:

Those methods alone should give you a moderate speedup. To be truly efficient, you may need to unroll the loop to allow for better IPC:

事情是这样的:

ans0 = 1
ans1 = 1
for i in range(1,(n+1) / 2):
    ans0 = ans0 * (2*i + 0) % modulus    
    ans1 = ans1 * (2*i + 1) % modulus    

return ans0 * ans1 % modulus

但考虑到用于迭代奇数#并将其与我挂上述的方法之一合成

but taking into account for an odd # of iterations and combining it with one of the methods I linked to above.

有些人可能认为循环展开应该留给编译器。我会反驳,认为编译器是目前没有足够的智慧来解开这个特殊的循环。仔细看看,你会明白为什么。

Some may argue that loop-unrolling should be left to the compiler. I will counter-argue that compilers are currently not smart enough to unroll this particular loop. Have a closer look and you will see why.

请注意,虽然我的答案是语言无关,是指主要为C或C ++。

Note that although my answer is language-agnostic, it is meant primarily for C or C++.

这篇关于快速的方法来计算N!模m其中m为质数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆