繁体   English   中英

即使将int修改为10 ^ 9 + 7,Oveflow

[英]Oveflow even when an int is mod by 10^9+7

我为数字的阶乘写了以下代码:

long int fac[max+1];
    fac[0]=1;


    for(int j=1;j<=max;j++)
        {
            fac[j]=(fac[j-1]*j)%1000000007;
        }


    //Printing
    for(int i=0;i<T;i++)
        {
            cout<<fac[N[i]]<<"\n";
        }

这对于int较长很有效,但是如果将数组更改为int,则会得到错误的答案。

请告诉我为什么当int的范围大于10 ^ 9 + 7时会发生这种情况。

int fac[max+1]; fac[j-1] * jint * int ,结果为int

如果溢出,您将拥有UB,即使未签名,也将丢失数据。

long int fac[max+1]; ,则fac[j-1] * jlong int * long intint > long int for j ),结果为long int

我们知道fac[j - 1] <10 9 fac[j - 1] * j 。但是fac[j - 1] * j将是该值的j倍,并且long偶尔只有32位长(Windows)。 可以放入32位数字中的绝对最大值是4294967295,仅是模数的四倍。

考虑使用unsigned long long而不是long int应该可以工作到j > 2 34为止。

实际上,鉴于(a * b) % N数学上等价(a % N) * (b % N)一旦用unsigned long long替换了long int就可以重写

fac[j] = (fac[j - 1] * j) % 1000000007

fac[j] = (fac[j - 1] * (j % 1000000007)) % 1000000007

然后,因为1000000007 2 <2 64 ,您应该可以永远继续进行此操作(当然,尽管最终您将用完fac的空间)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM