📄 cephes-old.c
字号:
0x5ebb,0x20dc,0x019f,0x3f4a,
0xa5a1,0x16b0,0xc16c,0xbf66,
0x554b,0x5555,0x5555,0x3fb5
};
static unsigned short B[] = {
0x6761,0x8ff3,0x8901,0xc095,
0xb93e,0x355b,0xf234,0xc0e2,
0x89e5,0xf890,0x3d73,0xc114,
0xdb51,0xf994,0xbc82,0xc131,
0xf20b,0x0219,0x4589,0xc13a,
0x055e,0x5418,0x0c67,0xc12a
};
static unsigned short C[] = {
/*0x0000,0x0000,0x0000,0x3ff0,*/
0x12b2,0x1cf3,0xfd0d,0xc075,
0xd757,0x7b89,0xaa0d,0xc0d0,
0x4c9b,0xb974,0xeb84,0xc10a,
0x0043,0x7195,0x6286,0xc131,
0xf34c,0x892f,0x5255,0xc143,
0xe14a,0x6a11,0xce4b,0xc13e
};
/* log( sqrt( 2*pi ) ) */
static unsigned short LS2P[] = {
0xbeb5,0xc864,0x67f1,0x3fed
};
#define LS2PI *(double *)LS2P
#define MAXLGM 2.556348e305
#endif
#ifdef MIEEE
static unsigned short A[] = {
0x3f4a,0x9850,0x2733,0x6661,
0xbf43,0x7fbd,0xb580,0xe943,
0x3f4a,0x019f,0x20dc,0x5ebb,
0xbf66,0xc16c,0x16b0,0xa5a1,
0x3fb5,0x5555,0x5555,0x554b
};
static unsigned short B[] = {
0xc095,0x8901,0x8ff3,0x6761,
0xc0e2,0xf234,0x355b,0xb93e,
0xc114,0x3d73,0xf890,0x89e5,
0xc131,0xbc82,0xf994,0xdb51,
0xc13a,0x4589,0x0219,0xf20b,
0xc12a,0x0c67,0x5418,0x055e
};
static unsigned short C[] = {
0xc075,0xfd0d,0x1cf3,0x12b2,
0xc0d0,0xaa0d,0x7b89,0xd757,
0xc10a,0xeb84,0xb974,0x4c9b,
0xc131,0x6286,0x7195,0x0043,
0xc143,0x5255,0x892f,0xf34c,
0xc13e,0xce4b,0x6a11,0xe14a
};
/* log( sqrt( 2*pi ) ) */
static unsigned short LS2P[] = {
0x3fed,0x67f1,0xc864,0xbeb5
};
#define LS2PI *(double *)LS2P
#define MAXLGM 2.556348e305
#endif
/* Logarithm of gamma function */
double lgam(double x)
{
double p, q, u, w, z;
int i;
sgngam = 1;
#ifdef NANS
if( isnan(x) )
return(x);
#endif
#ifdef INFINITIES
if( !isfinite(x) )
return(INFINITY);
#endif
if( x < -34.0 ) {
q = -x;
w = lgam(q); /* note this modifies sgngam! */
p = floor(q);
if( p == q ) {
lgsing:
#ifdef INFINITIES
mtherr( "lgam", SING );
return (INFINITY);
#else
goto loverf;
#endif
}
i = (int)p;
if( (i & 1) == 0 )
sgngam = -1;
else
sgngam = 1;
z = q - p;
if( z > 0.5 ) {
p += 1.0;
z = p - q;
}
z = q * sin( PI * z );
if( z == 0.0 )
goto lgsing;
/* z = log(PI) - log( z ) - w;*/
z = LOGPI - log( z ) - w;
return( z );
}
if( x < 13.0 ) {
z = 1.0;
p = 0.0;
u = x;
while( u >= 3.0 ) {
p -= 1.0;
u = x + p;
z *= u;
}
while( u < 2.0 ) {
if( u == 0.0 )
goto lgsing;
z /= u;
p += 1.0;
u = x + p;
}
if( z < 0.0 ) {
sgngam = -1;
z = -z;
}
else
sgngam = 1;
if( u == 2.0 )
return( log(z) );
p -= 2.0;
x = x + p;
p = x * polevl( x, B, 5 ) / p1evl( x, C, 6);
return( log(z) + p );
}
if( x > MAXLGM ) {
#ifdef INFINITIES
return( sgngam * INFINITY );
#else
loverf:
mtherr( "lgam", OVERFLOW );
return( sgngam * MAXNUM );
#endif
}
q = ( x - 0.5 ) * log(x) - x + LS2PI;
if( x > 1.0e8 )
return( q );
p = 1.0/(x*x);
if( x >= 1000.0 )
q += (( 7.9365079365079365079365e-4 * p
- 2.7777777777777777777778e-3) *p
+ 0.0833333333333333333333) / x;
else
q += polevl( p, A, 4 ) / x;
return( q );
}
/* mtherr.c
*
* Library common error handling routine
*
*
*
* SYNOPSIS:
*
* char *fctnam;
* int code;
* int mtherr();
*
* mtherr( fctnam, code );
*
*
*
* DESCRIPTION:
*
* This routine may be called to report one of the following
* error conditions (in the include file mconf.h).
*
* Mnemonic Value Significance
*
* DOMAIN 1 argument domain error
* SING 2 function singularity
* OVERFLOW 3 overflow range error
* UNDERFLOW 4 underflow range error
* TLOSS 5 total loss of precision
* PLOSS 6 partial loss of precision
* EDOM 33 Unix domain error code
* ERANGE 34 Unix range error code
*
* The default version of the file prints the function name,
* passed to it by the pointer fctnam, followed by the
* error condition. The display is directed to the standard
* output device. The routine then returns to the calling
* program. Users may wish to modify the program to abort by
* calling exit() under severe error conditions such as domain
* errors.
*
* Since all error conditions pass control to this function,
* the display may be easily changed, eliminated, or directed
* to an error logging device.
*
* SEE ALSO:
*
* mconf.h
*
*/
/*
Cephes Math Library Release 2.0: April, 1987
Copyright 1984, 1987 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
int mtherr(char *name, int code)
{
/* Display string passed by calling program,
* which is supposed to be the name of the
* function in which the error occurred:
*/
printf( "\n%s ", name );
/* Set global error message word */
merror = code;
/* Display error message defined
* by the code argument.
*/
if( (code <= 0) || (code >= 7) )
code = 0;
printf( "%s error\n", ermsg[code] );
return( 0 );
}
/* polevl.c
* p1evl.c
*
* Evaluate polynomial
*
*
*
* SYNOPSIS:
*
* int N;
* double x, y, coef[N+1], polevl[];
*
* y = polevl( x, coef, N );
*
*
*
* DESCRIPTION:
*
* Evaluates polynomial of degree N:
*
* 2 N
* y = C + C x + C x +...+ C x
* 0 1 2 N
*
* Coefficients are stored in reverse order:
*
* coef[0] = C , ..., coef[N] = C .
* N 0
*
* The function p1evl() assumes that coef[N] = 1.0 and is
* omitted from the array. Its calling arguments are
* otherwise the same as polevl().
*
*
* SPEED:
*
* In the interest of speed, there are no checks for out
* of bounds arithmetic. This routine is used by most of
* the functions in the library. Depending on available
* equipment features, the user may wish to rewrite the
* program in microcode or assembly language.
*
*/
/*
Cephes Math Library Release 2.1: December, 1988
Copyright 1984, 1987, 1988 by Stephen L. Moshier
Direct inquiries to 30 Frost Street, Cambridge, MA 02140
*/
double polevl(double x, double coef[], int N)
{
double ans;
int i;
double *p;
p = coef;
ans = *p++;
i = N;
do {
ans = ans * x + *p++;
} while( --i );
return(ans);
}
/* p1evl() */
/* N
* Evaluate polynomial when coefficient of x is 1.0.
* Otherwise same as polevl.
*/
double p1evl(double x, double coef[], int N)
{
double ans;
double *p;
int i;
p = coef;
ans = x + *p++;
i = N-1;
do {
ans = ans * x + *p++;
} while( --i );
return(ans);
}
/* error function in double precision */
double erf(double x)
{
int k;
double w, t, y;
static double a[65] = {
5.958930743e-11, -1.13739022964e-9,
1.466005199839e-8, -1.635035446196e-7,
1.6461004480962e-6, -1.492559551950604e-5,
1.2055331122299265e-4, -8.548326981129666e-4,
0.00522397762482322257, -0.0268661706450773342,
0.11283791670954881569, -0.37612638903183748117,
1.12837916709551257377,
2.372510631e-11, -4.5493253732e-10,
5.90362766598e-9, -6.642090827576e-8,
6.7595634268133e-7, -6.21188515924e-6,
5.10388300970969e-5, -3.7015410692956173e-4,
0.00233307631218880978, -0.0125498847718219221,
0.05657061146827041994, -0.2137966477645600658,
0.84270079294971486929,
9.49905026e-12, -1.8310229805e-10,
2.39463074e-9, -2.721444369609e-8,
2.8045522331686e-7, -2.61830022482897e-6,
2.195455056768781e-5, -1.6358986921372656e-4,
0.00107052153564110318, -0.00608284718113590151,
0.02986978465246258244, -0.13055593046562267625,
0.67493323603965504676,
3.82722073e-12, -7.421598602e-11,
9.793057408e-10, -1.126008898854e-8,
1.1775134830784e-7, -1.1199275838265e-6,
9.62023443095201e-6, -7.404402135070773e-5,
5.0689993654144881e-4, -0.00307553051439272889,
0.01668977892553165586, -0.08548534594781312114,
0.56909076642393639985,
1.55296588e-12, -3.032205868e-11,
4.0424830707e-10, -4.71135111493e-9,
5.011915876293e-8, -4.8722516178974e-7,
4.30683284629395e-6, -3.445026145385764e-5,
2.4879276133931664e-4, -0.00162940941748079288,
0.00988786373932350462, -0.05962426839442303805,
0.49766113250947636708
};
static double b[65] = {
-2.9734388465e-10, 2.69776334046e-9,
-6.40788827665e-9, -1.6678201321e-8,
-2.1854388148686e-7, 2.66246030457984e-6,
1.612722157047886e-5, -2.5616361025506629e-4,
1.5380842432375365e-4, 0.00815533022524927908,
-0.01402283663896319337, -0.19746892495383021487,
0.71511720328842845913,
-1.951073787e-11, -3.2302692214e-10,
5.22461866919e-9, 3.42940918551e-9,
-3.5772874310272e-7, 1.9999935792654e-7,
2.687044575042908e-5, -1.1843240273775776e-4,
-8.0991728956032271e-4, 0.00661062970502241174,
0.00909530922354827295, -0.2016007277849101314,
0.51169696718727644908,
3.147682272e-11, -4.8465972408e-10,
6.3675740242e-10, 3.377623323271e-8,
-1.5451139637086e-7, -2.03340624738438e-6,
1.947204525295057e-5, 2.854147231653228e-5,
-0.00101565063152200272, 0.00271187003520095655,
0.02328095035422810727, -0.16725021123116877197,
0.32490054966649436974,
2.31936337e-11, -6.303206648e-11,
-2.64888267434e-9, 2.050708040581e-8,
1.1371857327578e-7, -2.11211337219663e-6,
3.68797328322935e-6, 9.823686253424796e-5,
-6.5860243990455368e-4, -7.5285814895230877e-4,
0.02585434424202960464, -0.11637092784486193258,
0.18267336775296612024,
-3.67789363e-12, 2.0876046746e-10,
-1.93319027226e-9, -4.35953392472e-9,
1.8006992266137e-7, -7.8441223763969e-7,
-6.75407647949153e-6, 8.428418334440096e-5,
-1.7604388937031815e-4, -0.0023972961143507161,
0.0206412902387602297, -0.06905562880005864105,
0.09084526782065478489
};
w = x < 0 ? -x : x;
if (w < 2.2) {
t = w * w;
k = (int) t;
t -= k;
k *= 13;
y = ((((((((((((a[k] * t + a[k + 1]) * t +
a[k + 2]) * t + a[k + 3]) * t + a[k + 4]) * t +
a[k + 5]) * t + a[k + 6]) * t + a[k + 7]) * t +
a[k + 8]) * t + a[k + 9]) * t + a[k + 10]) * t +
a[k + 11]) * t + a[k + 12]) * w;
} else if (w < 6.9) {
k = (int) w;
t = w - k;
k = 13 * (k - 2);
y = (((((((((((b[k] * t + b[k + 1]) * t +
b[k + 2]) * t + b[k + 3]) * t + b[k + 4]) * t +
b[k + 5]) * t + b[k + 6]) * t + b[k + 7]) * t +
b[k + 8]) * t + b[k + 9]) * t + b[k + 10]) * t +
b[k + 11]) * t + b[k + 12];
y *= y;
y *= y;
y *= y;
y = 1 - y * y;
} else {
y = 1;
}
return x < 0 ? -y : y;
}
/* error function in double precision */
double erfc(double x)
{
double t, u, y;
t = 3.97886080735226 / (fabs(x) + 3.97886080735226);
u = t - 0.5;
y = (((((((((0.00127109764952614092 * u + 1.19314022838340944e-4) * u -
0.003963850973605135) * u - 8.70779635317295828e-4) * u +
0.00773672528313526668) * u + 0.00383335126264887303) * u -
0.0127223813782122755) * u - 0.0133823644533460069) * u +
0.0161315329733252248) * u + 0.0390976845588484035) * u +
0.00249367200053503304;
y = ((((((((((((y * u - 0.0838864557023001992) * u -
0.119463959964325415) * u + 0.0166207924969367356) * u +
0.357524274449531043) * u + 0.805276408752910567) * u +
1.18902982909273333) * u + 1.37040217682338167) * u +
1.31314653831023098) * u + 1.07925515155856677) * u +
0.774368199119538609) * u + 0.490165080585318424) * u +
0.275374741597376782) * t * exp(-x * x);
return x < 0 ? 2 - y : y;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -