当n变大时,难以计算factorial(n)mod m

时间:2014-03-07 16:02:54

标签: c++ arrays factorial

我正在尝试计算一个大素数的因子。

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;
}

2 个答案:

答案 0 :(得分:2)

我的猜测是你正在耗尽堆栈。对fact()的每次(递归)调用都会将一些值推送到程序的堆栈(返回地址,ABI规定的保存寄存器等)。堆栈的大小是固定的(取决于您的操作系统,您可以或多或少地更改它;如果您正在使用类似Bourne的shell,请参阅ulimit),所以最终,当您有这样的深度递归时,有一个“打破骆驼背部的稻草”,当你再打电话一次时,没有剩余的堆栈,你的程序会以某种错误信息退出(例如 Unix上的“分段违规”类似操作系统)。

正如特里斯坦在下面正确评论的那样,iterative factorial algorithm没有这个问题。

答案 1 :(得分:0)

32571是第一个出现的整数吗?

您是否尝试过将if(a<=1000000000ULL && b<=1000000000ULL)更改为if(a<mod && b<mod)后会发生什么?