我正在尝试计算以下值。
prod = 1;
for(int i=1;i<N;i++){
prod = prod*i;
}
由于N可能很大,我被要求计算模10^9+7
并且我做了。
int prod =1;
for(int i=1;i<N;i++)
{
prod = ((prod%1000000007) * (i%1000000007))%1000000007;
}
其他人也这样做了。
long ways=1;
for(int j=1;j<N;j++)
{
ways = (int)(j * ways % 1000000007);
}
在线评委认为第二个是正确的。为什么?
所以我跑了这个
int prod = 1;
long ways = 1;
for(int j=1;j<14;j++){
prod = ((prod%1000000007) * (j%1000000007))%1000000007;
ways = (int)(j * ways % 1000000007);
if(prod!=ways){
System.out.println(prod+" "+ways);
System.exit(0);
}
System.out.println(prod+" "+ways+" "+j);
}
当prod or ways
为479001600
且j
在下一次迭代中为12
时,它们并不相等。两者都小于int max,即2147483647
所以我这样做,他们是平等的
prod = ((479001600%1000000007) * (12%1000000007))%1000000007;
ways = (int)(12 * 479001600 % 1000000007);
if(prod!=ways){
System.out.println(prod+" "+ways);
System.exit(0);
}
System.out.println(prod+" "+ways);
我认为这是铸造的东西。但无法弄清楚。请告诉我,如果我做错了什么?
答案 0 :(得分:3)
Haven没有完成Java一段时间,但这似乎与语言无关(并且与模数无关):您正在使用int(prod
),另一个解决方案使用long({{1 }})。
变量(ways
或prod
)与ways
(此处为12)的乘法是溢出的。 479001600 * 12是5,748,019,200。如果两个参数都是int,则会溢出。最大的32位值是4,294,967,295。
如果表达式的一边是长的,那么结果将是一个长的 - >&gt;没有溢出。
答案 1 :(得分:0)
转换不是问题,但将prod
更改为long
的数据类型将解决您的问题。这样做的原因是,当j=13
甚至很难获得结果的模数时,乘法会溢出。