[英]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] * j
是int * int
,结果为int
。
如果溢出,您将拥有UB,即使未签名,也将丢失数据。
long int fac[max+1];
,则fac[j-1] * j
是long int * long int
( int
> 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.