#include <math.h>
#include <stdio.h>
#define sign(x) (x == 0 ? 0 : (x < 0 ? -1 : 1))
const double pi_const=0.3989422804014;
int N;
double
D(double x, double eps)
{
double x1, xn,g0, g1, s=0, sum, t, z;
static const double PHI[] = {
0.5, /* x=0 */
0.841344746068543, /* x=1 */
0.977249868051821, /* x=2 */
0.998650101968370, /* x=3 */
0.999968328758167, /* x=4 */
0.999999713348428, /* x=5 */
0.999999999013412, /* x=6 */
0.999999999998720, /* x=7 */
0.999999999999999 /* x=8 */
},
H=1.0;
int i, n;
x1=fabs(x); i=(int)(x1/H+0.5); z=i*H;
g0=t=PHI[i]; g1=exp(-z*z/2.)*pi_const;
xn=(x1-=z); sum=t+g1*xn;
N=0;
for(n=2;fabs(s-t) > eps || fabs(t-sum) > eps; n++) {
s=-z*g1-(n-2)*g0; g0=g1; g1=s; xn*=x1/n;
s=t; t=sum; sum+=g1*xn;
N++; /* Внешняя переменная! */
}
return (x>0 ? sum : 1-sum);
}
double
P(double x, double eps)
{
double x1, xn,c0, c1, rz, s, t=0, z;
int i, n;
static const double R[] = {
0.,
1.4106861306,
8.8394391760,
112.51515173,
3735.8400745,
336310.71435,
82292564.750,
54736210525.,
98965389434000.
},
H=1.0;
x1=fabs(x); i=(int)(x1/H+0.5); z=i*H;
c0=s=R[i]; c1=1.+z*c0;
xn=(x1-=z); rz=s+c1*xn;
N=0;
for(n=2; fabs(s-t) > eps || fabs(t-rz) > eps; n++) {
s=(c0+c1*z)/n; c0=c1; c1=s; xn*=x1;
s=t; t=rz; rz+=c1*xn;
N++; /* Внешняя переменная! */
}
return 0.5+sign(x)*rz*exp(-x*x/2)*pi_const;
}
double
F(double x, double eps)
{
double x1=fabs(x), a, z=0, fz=0;
double t, s, sum, xn, g0, g1;
int n;
double h=0.25;
N=0;
while((a=x1-z)>0) {
if (a > h) a = h;
/* Подготовка к вычислению ряда. */
xn = a; g0 = g1 = exp(-z*z/2)*pi_const;
t = sum = g1*xn;
for(n=2, s=0;(fabs(s-t)>eps) || (fabs(t-sum)>eps); n++) {
N++; /* Внешняя переменная! */
/* Вычислим очередную частичную сумму */
xn *= a/n; s = -z*g1-(n-2)*g0;
g0 = g1; g1 = s; s = t; t = sum; sum += g1*xn;
};
/* В т. z разложение посчитано - пошли дальше */
fz += sum; z += a;
}
return 0.5 + sign(x)*fz;
}
double
C(double x, double eps)
{
double x1, ra, rz, z, d;
double t, s, xa, xn, c0, c1;
int n, gotta=0;
double h=0.5;
x1=fabs(x); rz=t=z=0;
N=0;
while(!gotta) {
xa=z; ra=rz; z+=h;
if(z >= x1) {
z = x1; gotta = 1;
}
c0=s=ra; c1=1.+xa*ra;
xn=d=z-xa; rz=ra+c1*xn;
for(n=2;(fabs(s-t)>eps) || (fabs(s-rz)>eps); n++) {
N++; /* Внешняя переменная! */
/* Вычислим очередную частичную сумму */
t=(c0+xa*c1)/n; c0=c1; c1=t; xn*=d;
t=s; s=rz; rz=s+c1*xn;
}
}
return 0.5 + sign(x)*rz*exp(-x*x/2)*pi_const;
}
double
B(double x, double eps)
{
double x1=fabs(x), fz=0;
double t, s, sum, xn, g0, g1;
int n;
double a=0.5;
N=0;
while(x1>0) {
if (x1 <= a) a = x1;
/* Подготовка к вычислению ряда. */
xn = a; g0 = g1 = exp(-x1*x1/2)*pi_const;
t = sum = g1*xn;
for(n=2, s=0;(fabs(s-t)>eps) || (fabs(t-sum)>eps); n++) {
N++; /* Внешняя переменная! */
/* Вычислим очередную частичную сумму */
xn *= -a/n; s = -x1*g1-(n-2)*g0;
g0 = g1; g1 = s; s = t; t = sum; sum += g1*xn;
}
/* В т. z разложение посчитано - пошли дальше */
fz += sum; x1 -= a;
}
return 0.5 + sign(x)*fz;
}
double
E(double x, double eps)
{
double x1=fabs(x)*0.707106781186548, z=0;
double y, s, xn, u, v, w=0;
int n;
double a=0.5;
N=0;
while(x1>0) {
if (x1 <= a) a = x1;
/* Подготовка к вычислению ряда. */
xn = a; u = v = exp(-x1*x1)*0.564189583547756;
s = y = v*a;
for(n=2;(fabs(w-s)>eps) || (fabs(s-y)>eps); n++) {
N++; /* Внешняя переменная! */
/* Вычислим очередную частичную сумму */
w=-2.*(x1*v+u*(n-2.));
u=v; v=w; xn*=-a/n; w=s; s=y; y+= v*xn;
}
/* В т. z разложение посчитано - пошли дальше */
z+=y; x1-=a;
}
return 0.5 + sign(x)*z;
}
void main(void)
{
double x;
double f;
for(x=0.25; x<8; x+=0.25) {
#ifdef TABLE
printf("\n %4.2f", x);
f = D(x,0);
printf("\t%d", N);
f = P(x,0);
printf("\t%d", N);
f = C(x,0);
printf("\t%d", N);
f = B(x,0);
printf("\t%d", N);
f = E(x,0);
printf("\t%d", N);
#else
f = D(x,0);
printf("\nD(%4.2f)=%10.8g\t%d", x, f, N);
f = P(x,0);
printf("\nP(%4.2f)=%10.8g\t%d", x, f, N);
f = C(x,0);
printf("\nC(%4.2f)=%10.8g\t%d", x, f, N);
f = B(x,0);
printf("\nB(%4.2f)=%10.8g\t%d", x, f, N);
f = E(x,0);
printf("\nE(%4.2f)=%10.8g\t%d", x, f, N);
#endif
}
}
|