我正在尝试计算一个大素数的因子。
arr[]
存储各种数字的阶乘的值
如果我先计算fact(32570)
然后再打印arr[1]
和arr[2]
,那就行了。
如果我先计算fact(32571)
,然后打印arr[1]
和arr[2]
,那么这不起作用。
但是,仅计算fact(32571)
有效。
我真的无法调试此代码。
另外,
独立计算fact(32572)
不起作用。
但是,如果我在找到fact(32572)
后计算fact(32571)
,则可以正常使用。
这是怎么回事?
#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;
}
答案 0 :(得分:2)
我的猜测是你正在耗尽堆栈。对fact()
的每次(递归)调用都会将一些值推送到程序的堆栈(返回地址,ABI规定的保存寄存器等)。堆栈的大小是固定的(取决于您的操作系统,您可以或多或少地更改它;如果您正在使用类似Bourne的shell,请参阅ulimit
),所以最终,当您有这样的深度递归时,有一个“打破骆驼背部的稻草”,当你再打电话一次时,没有剩余的堆栈,你的程序会以某种错误信息退出(例如 Unix上的“分段违规”类似操作系统)。
正如特里斯坦在下面正确评论的那样,iterative factorial algorithm没有这个问题。
答案 1 :(得分:0)
32571是第一个出现的整数吗?
您是否尝试过将if(a<=1000000000ULL && b<=1000000000ULL)
更改为if(a<mod && b<mod)
后会发生什么?