问题
I am trying to compute factorial of large numbers mod a large prime number.
arr[]
stores the value of the factorials for various numbers
If I calculate fact(32570)
first and then print arr[1]
and arr[2]
, then that works.
If I calculate fact(32571)
first and then print arr[1]
and arr[2]
, then that does not work.
However, calculating only fact(32571)
works.
I really cannot debug this code.
Also,
calculating fact(32572)
independently does not work.
But, if I calculate fact(32572)
after finding fact(32571)
then that works okay.
Whats going on here?
#define LL unsigned long long
#define ull unsigned long long
const LL mod=1000000009;
LL arr[1048580];
inline ull mulMod(ull a,ull b,ull c)
{
if(a<=1000000000ULL && b<=1000000000ULL)
{
//cout<<((a%c)*(b%c))%c<<endl;
ull ret = ((a%c)*(b%c))%c; //also giving segmentation fault
return ret;
}
ull ret = 0ULL; a=a%c;
while(b > 0ULL)
{
if(b&1ULL) ret = ((ret%c)+(a%c))%c;
a = (a<<1ULL)%c;
b>>=1ULL;
}
return ret%c;
}
LL fact(LL num)
{
if(arr[num]==0)
{
arr[num]=mulMod(num,fact(num-1),mod); //gives segmentation fault
return arr[num];
}
return arr[num];
}
int main()
{
arr[0]=1;
// does not work
// cout<<fact(32571)<<endl;
// cout<<arr[1]<<" "<<arr[2]<<endl;
//works
// cout<<fact(325)<<endl;
// cout<<arr[1]<<" "<<arr[2]<<endl;
//also works
cout<<fact(32571)<<endl;
}
回答1:
My guess is that you're running out of stack. Every (recursive) call to fact()
pushes a few values onto the program's stack (return address, saved registers mandated by ABI, etc.). The size of the stack is fixed (depending on your OS, you can change it more or less easily; see ulimit
if you're using a Bourne-like shell), so eventually, when you have deep recursion like this, there is a “straw that breaks the camel's back”, and when you call one more time, there's no stack left and your program exits with an error message of some kind (e.g. “Segmentation violation” on Unix-like OSs).
As Tristan correctly comments below, an iterative factorial algorithm does not have this problem.
回答2:
Is 32571 the first integer for which it occurs?
Have you tried out what happens when you change if(a<=1000000000ULL && b<=1000000000ULL)
to if(a<mod && b<mod)
?
来源:https://stackoverflow.com/questions/22254901/having-difficulty-in-computing-factorialn-mod-m-when-n-gets-large