2017-05-04 11 views
0

私は単純な超幾何テストをcで記述しようとしています。 このコードは小数に対しては機能しますが、大きな数値では失敗します。例えばプログラム受信信号SIGSEGV、セグメンテーションフォールト./sysdeps/ieee754/dbl-64/e_log.c:そのようなファイルやディレクトリはありません

:hyperG 35 50 90 3400 -

に動作しますが、hyperG ./hyperG 307107 486302 9073845 12147105 --fails

オンラインデバッガを使用して私が取得:

プログラムは、信号を受信SIGSEGV 、セグメンテーションフォルト。
__ieee754_log_avx(x = 2898563)../sysdeps/ieee754/dbl-64/e_log.c:76
76 ../sysdeps/ieee754/dbl-64/e_log.c:このようなファイルやディレクトリはありません。

何か提案がありがとうございます。

#include <stdio.h> 
    #include <stdlib.h> 
    #include <math.h> 
    /* 
    * program: hyperG 
    * purpose: Calculate a probability based on a hypergeometric distribution 
    * input : k, n, M, N 
    * output : Return a probability 
    * 
    */ 
    // Variables 
    double k = 0.0; 
    double n = 0.0; 
    double M = 0.0; 
    double N = 0.0; 

    double logchoos(double n, double k); 
    double logfact(double n); 

//Probability of at least k out of n tries of having something 
//that occurs M of of N times 
double hypergeometric(double k, double n, double M, double N) 
{ 
    double p = 0.0; 
    int i = 0; 

    for(i = k; i <= n; i++){ 
     p += exp(logchoos((N-M),(n-i)) + logchoos(M,i) - logchoos(N,n)); 
    } 

    return p; 
} 

// compute log "n choose k" or n = n!/(n-k)!k! 
double logchoos(double n, double k) 
{ 
    double result = logfact(n) - logfact(n-k) - logfact(k); 

    return result; 
} 

// Calculate the log factorial 
double logfact(double n) 
{ 
    double fac; 

    if(n < 1) 
     return 0.0; 
    else 
     fac = log(n) + logfact(n-1); 

    return(fac); 
} 


int main(int argc, char *argv[]) 
{ 
    // Get command line arguments 
    k = atof(argv[1]); 
    n = atof(argv[2]); 
    M = atof(argv[3]); 
    N = atof(argv[4]); 

    double prob = hypergeometric(k,n,M,N); 

    printf("%e\n",prob); 

    return 0; 
} 

私のメイクファイル:

コードは次の値が小さいためにその作業として

Makefile 
CC = gcc 
CFLAGS = -Wall -g 
LDFLAGS = -lm 
FILES = hyperG.c 

build: $(FILES) 
    $(CC) $(FILES) -o hyperG $(CFLAGS) $(LDFLAGS) 
clean: 
    rm -f hyperG 
+0

数学共有ライブラリ 'libm'が見つからないようです。 – jiveturkey

+0

小さい値では動作しますが大きな値では失敗するため、再帰的なlogfact関数でスタックが不足している可能性があります – Pras

+0

コンパイラでライブラリを見つける方法を教えてください。 libは次の場所にあります。/usr/lib/x86_64-linux-gnu/libm.a – mplace

答えて

0

を、より大きい値で失敗したあなたはしばらくループに再帰を変更した場合、そのはおそらく、スタックが不足しています307107 486302 9073845 12147105を入力としてセグメンテーションしませんが、実行を完了するまでに多くの時間がかかります。

double logfact(double n) 
{ 
    double fac = 0; 
    while(n > 1) 
    { 
     fac += log(n); 
     n = n-1; 
    } 

    return(fac); 
} 
関連する問題