[英]Why is this program giving me a SIGFPE?
我在下面的程序中收到SIGFPE错误,无法想到将其删除的方法。
#include <stdio.h>
unsigned int fact(unsigned long int n)
{
if (n <= 0)
return 1;
return n*fact(n-1);
}
int main(){
int t,r,x,y,z,sum=0,n;
scanf("%d",&t);
for(int l=0; l<t; l++){
scanf("%d",&n );
if(n%2==0){
for(int j=n,i=0,k=n; k>=0&&j>0;i++, j++,k-=2){
x=fact(n-i);
y=fact(k);
z=fact(n-k-i);
sum=sum+ (x)/(y*z);
}
printf("%d\n",sum );
}
if(n%2!=0){
for(int j=n,i=0,k=n; k>=1&&j>0;i++, j++,k-=2){
x=fact(n-i);
y=fact(k);
z=fact(n-k-i);
sum=sum+ (x)/(y*z);
}
printf("%d\n",sum);
}
sum=0;
}
return 0;
}
我正在尝试计算需要阶乘的级数,但这给了我SIGFPE错误。 我使用35
作为输入。
链接到问题: 屏幕截图
35! 远远超过了平台上unsigned int
的容量。
会发生什么然后是fact(35)
返回0,其结果在被零除因此SIGFPE(F loating p ointëxception)。
考虑使用unsigned long long
类型,但这对35也不起作用,因为35! 真的很大
除了Jabberwocky的答案。
溢出不是唯一的原因,哦,有一个“整数”溢出...
fact(34)返回惊人的结果0。
如果是uint64
返回值, uint64
返回arg
unsigned long long fact(unsigned long long n)
然后用
printf("%llx",x);
您将得到结果:445da75b00000000
将其强制转换为int即可得到完美的0。
这是合乎逻辑的,因为您已将许多偶数相乘,并且有些数字是2的偶数幂。
在您的程序中,您将为每个可能的两个任务天数计算二项式系数C(n,k)。 公式很简单:
C(n, k) = n! / (k! * (n - k)!)
但是直接使用此公式有几个问题:中间结果,即阶乘,迅速溢出。 无符号的32位整数最多可容纳12!个事实,无符号的64位整数最多可容纳20!个,但是此后,您将需要bignum库。 问题陈述指出,任务数N最多为80。我相信选择了此限制,以便您可以使用<stdint.h>
uint64_t
进行所有计算。
还有其他问题; 雷蒙·陈(Raymond Chen)尽我所能勾勒出它们的优美轮廓。 他还提出了一种计算二项式系数的简单方法,您可以采用:
uint64_t binom(uint64_t n, uint64_t k)
{
uint64_t c = 1u;
uint64_t i;
for (i = 0; i < k; i++) {
c *= n - i;
c /= i + 1;
}
return c;
}
哦,您不需要区分N的奇数和偶数。
挑战有一个奇怪的地方:N是每个测试用例的唯一参数,范围可以从1到80,但是最多可以有10,000个测试用例。 如果超过80个,N将重复。 也许他们希望您将结果记忆在一个数组中,以便第一次计算该结果时将其存储起来,而下次您必须再次针对相同的N计算时,只需使用预先计算的值即可。 这样可以节省时间,并且“超过时间限制”是在线竞赛中非常常见的错误。
您也可以尝试计算前几个结果,例如N的范围是1到10,并打印出来。 注意到模式吗? 看,您根本不需要二项式系数。 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.