[英]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.