最近几次碰到乘法溢出,
情况一:
下面是修订后的版本
void dfs(int pos, int lim, int val, int div)
{
int i,j;
if(pos>prime[0]||prime[pos]>lim) return;
int t=prime[pos];
for(i=1,j=1; i<=lim/t;j++){
i*=t;
divisor[val*i]=div*(j+1);
dfs(pos+1,lim/i,val*i,div*(j+1));
}
dfs(pos+1,lim,val,div);
}
原来的版本是for(i=1,j=1; i*t<=lim;j++),结果i*t溢出变成负数导致divisor[val*i]的下标为负
情况二多一个乘法,导致顾此失彼: LIMIT 是500000,在下面的for循环
for(t=prime[ob.ind];t<=LIM/ob.cur;t*=prime[ob.ind])
t是第4793个质数46349,ob.cur为8,导致t*=prime[ob.ind]会产生乘法溢出(超过2^31-1),其实t<=LIM/ob.cur已经是为了避免乘法溢出的做法,结果还是没有考虑到后面的乘法。
程序运行最终产生了access violation(VC),因为divs[t*ob.cur]的下标出现了一个大负数。
解决的办