我写的程序。在gfg的实践环境下运行:
class Solution{
public:
int nCr(int n, int r){
// code here
enter code here const unsigned int M = 1000000007;
long long dp[n+1]={0},i,ans;
if(n<r)
return 0;
dp[0]=1;
dp[1]=1;
for(i=2;i<=n;i++){
dp[i]=i*dp[i-1];
}
ans=(dp[n])/(dp[n-r]*dp[r]);
ans=ans%M;
return ans;
}
};
不明白发生了什么。划分似乎很清楚。
划分似乎很明确。
你怀疑除法是SIGFPE错误的根源是正确的。如你所知,除法是有定义的,只要除数不为零。乍一看,人们不会想到dp[n-r]*dp[r]
会变为零。但是dp
中的元素所能容纳的值范围是有限的。对于64位的long long
,最大可表示值通常为263−1 = 9223372036854775807。这意味着dp[i]
已经溢出i
>尽管在普通处理器上,这个溢出会被静默地忽略。现在,随着用更大的i
值进行乘乘计算阶乘,越来越多的零被"移进"了。从右到最后64位都为零;这是在普通处理器上i
= 66,当n-r
或r
等于或大于66时发生异常。