static double q_gamma(double a, double x, double log_gamma_a) { double y,w,la=1.0,lb=x+1.0-a,lc; int i; if (x<a+1.0) return 1.0-p_gamma(a,x,log_gamma_a); w=exp(-x+a*log(x)-log_gamma_a); y=w/lb; for (i=2;i<100;i++) { lc=((i-1-a)*(lb-la)+(i+x)*lb)/i; la=lb; lb=lc; w*=(i-1-a)/i; y+=w/la/lb; if (fabs(w/la/lb)<1E-15) break; } return y; }
static double f_erfc(double x) { return x>=0.0?q_gamma(0.5,x*x,LOG_PI/2.0):1.0+p_gamma(0.5,x*x,LOG_PI/2.0); }