模除法期间的整数溢出

时间:2016-12-02 14:24:08

标签: java modulo

我正在尝试计算以下值。

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 ways479001600j在下一次迭代中为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);

我认为这是铸造的东西。但无法弄清楚。请告诉我,如果我做错了什么?

2 个答案:

答案 0 :(得分:3)

Haven没有完成Java一段时间,但这似乎与语言无关(并且与模数无关):您正在使用int(prod),另一个解决方案使用long({{1 }})。

变量(waysprod)与ways(此处为12)的乘法是溢出的。 479001600 * 12是5,748,019,200。如果两个参数都是int,则会溢出。最大的32位值是4,294,967,295。

如果表达式的一边是长的,那么结果将是一个长的 - >&gt;没有溢出。

答案 1 :(得分:0)

转换不是问题,但将prod更改为long的数据类型将解决您的问题。这样做的原因是,当j=13甚至很难获得结果的模数时,乘法会溢出。