Initial revision

This commit is contained in:
Ben Gras
2005-04-21 14:53:53 +00:00
commit 9865aeaa79
2264 changed files with 411685 additions and 0 deletions

97
lib/math/Makefile Executable file
View File

@@ -0,0 +1,97 @@
# Makefile for lib/math.
CFLAGS = -O -D_MINIX -D_POSIX_SOURCE
CC1 = $(CC) $(CFLAGS) -c
LIBRARY = ../libc.a
all: $(LIBRARY)
OBJECTS = \
$(LIBRARY)(asin.o) \
$(LIBRARY)(atan.o) \
$(LIBRARY)(atan2.o) \
$(LIBRARY)(ceil.o) \
$(LIBRARY)(exp.o) \
$(LIBRARY)(fabs.o) \
$(LIBRARY)(floor.o) \
$(LIBRARY)(fmod.o) \
$(LIBRARY)(frexp.o) \
$(LIBRARY)(hugeval.o) \
$(LIBRARY)(isnan.o) \
$(LIBRARY)(ldexp.o) \
$(LIBRARY)(log.o) \
$(LIBRARY)(log10.o) \
$(LIBRARY)(modf.o) \
$(LIBRARY)(pow.o) \
$(LIBRARY)(sin.o) \
$(LIBRARY)(sinh.o) \
$(LIBRARY)(sqrt.o) \
$(LIBRARY)(tan.o) \
$(LIBRARY)(tanh.o) \
$(LIBRARY): $(OBJECTS)
aal cr $@ *.o
rm *.o
$(LIBRARY)(asin.o): asin.c
$(CC1) asin.c
$(LIBRARY)(atan.o): atan.c
$(CC1) atan.c
$(LIBRARY)(atan2.o): atan2.c
$(CC1) atan2.c
$(LIBRARY)(ceil.o): ceil.c
$(CC1) ceil.c
$(LIBRARY)(exp.o): exp.c
$(CC1) exp.c
$(LIBRARY)(fabs.o): fabs.c
$(CC1) fabs.c
$(LIBRARY)(floor.o): floor.c
$(CC1) floor.c
$(LIBRARY)(fmod.o): fmod.c
$(CC1) fmod.c
$(LIBRARY)(frexp.o): frexp.s
$(CC1) frexp.s
$(LIBRARY)(hugeval.o): hugeval.c
$(CC1) hugeval.c
$(LIBRARY)(isnan.o): isnan.c
$(CC1) isnan.c
$(LIBRARY)(ldexp.o): ldexp.c
$(CC1) ldexp.c
$(LIBRARY)(log.o): log.c
$(CC1) log.c
$(LIBRARY)(log10.o): log10.c
$(CC1) log10.c
$(LIBRARY)(modf.o): modf.s
$(CC1) modf.s
$(LIBRARY)(pow.o): pow.c
$(CC1) pow.c
$(LIBRARY)(sin.o): sin.c
$(CC1) sin.c
$(LIBRARY)(sinh.o): sinh.c
$(CC1) sinh.c
$(LIBRARY)(sqrt.o): sqrt.c
$(CC1) sqrt.c
$(LIBRARY)(tan.o): tan.c
$(CC1) tan.c
$(LIBRARY)(tanh.o): tanh.c
$(CC1) tanh.c

82
lib/math/asin.c Executable file
View File

@@ -0,0 +1,82 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <errno.h>
#include "localmath.h"
static double
asin_acos(double x, int cosfl)
{
int negative = x < 0;
int i;
double g;
static double p[] = {
-0.27368494524164255994e+2,
0.57208227877891731407e+2,
-0.39688862997540877339e+2,
0.10152522233806463645e+2,
-0.69674573447350646411e+0
};
static double q[] = {
-0.16421096714498560795e+3,
0.41714430248260412556e+3,
-0.38186303361750149284e+3,
0.15095270841030604719e+3,
-0.23823859153670238830e+2,
1.0
};
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (negative) {
x = -x;
}
if (x > 0.5) {
i = 1;
if (x > 1) {
errno = EDOM;
return 0;
}
g = 0.5 - 0.5 * x;
x = - sqrt(g);
x += x;
}
else {
/* ??? avoid underflow ??? */
i = 0;
g = x * x;
}
x += x * g * POLYNOM4(g, p) / POLYNOM5(g, q);
if (cosfl) {
if (! negative) x = -x;
}
if ((cosfl == 0) == (i == 1)) {
x = (x + M_PI_4) + M_PI_4;
}
else if (cosfl && negative && i == 1) {
x = (x + M_PI_2) + M_PI_2;
}
if (! cosfl && negative) x = -x;
return x;
}
double
asin(double x)
{
return asin_acos(x, 0);
}
double
acos(double x)
{
return asin_acos(x, 1);
}

72
lib/math/atan.c Executable file
View File

@@ -0,0 +1,72 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <float.h>
#include <math.h>
#include <errno.h>
#include "localmath.h"
double
atan(double x)
{
/* Algorithm and coefficients from:
"Software manual for the elementary functions"
by W.J. Cody and W. Waite, Prentice-Hall, 1980
*/
static double p[] = {
-0.13688768894191926929e+2,
-0.20505855195861651981e+2,
-0.84946240351320683534e+1,
-0.83758299368150059274e+0
};
static double q[] = {
0.41066306682575781263e+2,
0.86157349597130242515e+2,
0.59578436142597344465e+2,
0.15024001160028576121e+2,
1.0
};
static double a[] = {
0.0,
0.52359877559829887307710723554658381, /* pi/6 */
M_PI_2,
1.04719755119659774615421446109316763 /* pi/3 */
};
int neg = x < 0;
int n;
double g;
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (neg) {
x = -x;
}
if (x > 1.0) {
x = 1.0/x;
n = 2;
}
else n = 0;
if (x > 0.26794919243112270647) { /* 2-sqtr(3) */
n = n + 1;
x = (((0.73205080756887729353*x-0.5)-0.5)+x)/
(1.73205080756887729353+x);
}
/* ??? avoid underflow ??? */
g = x * x;
x += x * g * POLYNOM3(g, p) / POLYNOM4(g, q);
if (n > 1) x = -x;
x += a[n];
return neg ? -x : x;
}

42
lib/math/atan2.c Executable file
View File

@@ -0,0 +1,42 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <errno.h>
#include "localmath.h"
double
atan2(double y, double x)
{
double absx, absy, val;
if (x == 0 && y == 0) {
errno = EDOM;
return 0;
}
absy = y < 0 ? -y : y;
absx = x < 0 ? -x : x;
if (absy - absx == absy) {
/* x negligible compared to y */
return y < 0 ? -M_PI_2 : M_PI_2;
}
if (absx - absy == absx) {
/* y negligible compared to x */
val = 0.0;
}
else val = atan(y/x);
if (x > 0) {
/* first or fourth quadrant; already correct */
return val;
}
if (y < 0) {
/* third quadrant */
return val - M_PI;
}
return val + M_PI;
}

20
lib/math/ceil.c Executable file
View File

@@ -0,0 +1,20 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
double
ceil(double x)
{
double val;
return modf(x, &val) > 0 ? val + 1.0 : val ;
/* this also works if modf always returns a positive
fractional part
*/
}

72
lib/math/exp.c Executable file
View File

@@ -0,0 +1,72 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <float.h>
#include <errno.h>
#include "localmath.h"
double
exp(double x)
{
/* Algorithm and coefficients from:
"Software manual for the elementary functions"
by W.J. Cody and W. Waite, Prentice-Hall, 1980
*/
static double p[] = {
0.25000000000000000000e+0,
0.75753180159422776666e-2,
0.31555192765684646356e-4
};
static double q[] = {
0.50000000000000000000e+0,
0.56817302698551221787e-1,
0.63121894374398503557e-3,
0.75104028399870046114e-6
};
double xn, g;
int n;
int negative = x < 0;
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (x < M_LN_MIN_D) {
errno = ERANGE;
return 0.0;
}
if (x > M_LN_MAX_D) {
errno = ERANGE;
return HUGE_VAL;
}
if (negative) x = -x;
/* ??? avoid underflow ??? */
n = x * M_LOG2E + 0.5; /* 1/ln(2) = log2(e), 0.5 added for rounding */
xn = n;
{
double x1 = (long) x;
double x2 = x - x1;
g = ((x1-xn*0.693359375)+x2) - xn*(-2.1219444005469058277e-4);
}
if (negative) {
g = -g;
n = -n;
}
xn = g * g;
x = g * POLYNOM2(xn, p);
n += 1;
return (ldexp(0.5 + x/(POLYNOM3(xn, q) - x), n));
}

13
lib/math/fabs.c Executable file
View File

@@ -0,0 +1,13 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
double
fabs(double x)
{
return x < 0 ? -x : x;
}

20
lib/math/floor.c Executable file
View File

@@ -0,0 +1,20 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
double
floor(double x)
{
double val;
return modf(x, &val) < 0 ? val - 1.0 : val ;
/* this also works if modf always returns a positive
fractional part
*/
}

34
lib/math/fmod.c Executable file
View File

@@ -0,0 +1,34 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Eck
*/
/* $Header$ */
#include <math.h>
#include <errno.h>
double
fmod(double x, double y)
{
long i;
double val;
double frac;
if (y == 0) {
errno = EDOM;
return 0;
}
frac = modf( x / y, &val);
return frac * y;
/*
val = x / y;
if (val > LONG_MIN && val < LONG_MAX) {
i = val;
return x - i * y;
}
*/
}

35
lib/math/frexp.s Executable file
View File

@@ -0,0 +1,35 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
.extern _frexp
.sect .text
_frexp:
#if __i386
push ebp
mov ebp, esp
push 12(ebp)
push 8(ebp)
mov eax, esp
add eax, -4
push eax
call .fef8
mov eax, 16(ebp)
pop (eax)
pop eax
pop edx
leave
ret
#else /* i86 */
push bp
mov bp, sp
lea bx, 4(bp)
mov cx, #8
call .loi
mov ax, sp
add ax, #-2
push ax
call .fef8
mov bx, 12(bp)
pop (bx)
call .ret8
jmp .cret
#endif

14
lib/math/hugeval.c Executable file
View File

@@ -0,0 +1,14 @@
/*
* (c) copyright 1990 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Hans van Eck
*/
/* $Header$ */
#include <math.h>
double
__huge_val(void)
{
return 1.0e+1000; /* This will generate a warning */
}

11
lib/math/isnan.c Executable file
View File

@@ -0,0 +1,11 @@
int __IsNan(double d)
{
#if defined(vax) || defined(pdp)
#else
float f = d;
if ((*((long *) &f) & 0x7f800000) == 0x7f800000 &&
(*((long *) &f) & 0x007fffff) != 0) return 1;
#endif
return 0;
}

55
lib/math/ldexp.c Executable file
View File

@@ -0,0 +1,55 @@
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/* $Header$ */
#include <math.h>
#include <float.h>
#include <errno.h>
double
ldexp(double fl, int exp)
{
int sign = 1;
int currexp;
if (__IsNan(fl)) {
errno = EDOM;
return fl;
}
if (fl == 0.0) return 0.0;
if (fl<0) {
fl = -fl;
sign = -1;
}
if (fl > DBL_MAX) { /* for infinity */
errno = ERANGE;
return sign * fl;
}
fl = frexp(fl,&currexp);
exp += currexp;
if (exp > 0) {
if (exp > DBL_MAX_EXP) {
errno = ERANGE;
return sign * HUGE_VAL;
}
while (exp>30) {
fl *= (double) (1L << 30);
exp -= 30;
}
fl *= (double) (1L << exp);
}
else {
/* number need not be normalized */
if (exp < DBL_MIN_EXP - DBL_MANT_DIG) {
return 0.0;
}
while (exp<-30) {
fl /= (double) (1L << 30);
exp += 30;
}
fl /= (double) (1L << -exp);
}
return sign * fl;
}

42
lib/math/localmath.h Executable file
View File

@@ -0,0 +1,42 @@
/*
* localmath.h - This header is used by the mathematical library.
*/
/* $Header$ */
/* some constants (Hart & Cheney) */
#define M_PI 3.14159265358979323846264338327950288
#define M_2PI 6.28318530717958647692528676655900576
#define M_3PI_4 2.35619449019234492884698253745962716
#define M_PI_2 1.57079632679489661923132169163975144
#define M_3PI_8 1.17809724509617246442349126872981358
#define M_PI_4 0.78539816339744830961566084581987572
#define M_PI_8 0.39269908169872415480783042290993786
#define M_1_PI 0.31830988618379067153776752674502872
#define M_2_PI 0.63661977236758134307553505349005744
#define M_4_PI 1.27323954473516268615107010698011488
#define M_E 2.71828182845904523536028747135266250
#define M_LOG2E 1.44269504088896340735992468100189213
#define M_LOG10E 0.43429448190325182765112891891660508
#define M_LN2 0.69314718055994530941723212145817657
#define M_LN10 2.30258509299404568401799145468436421
#define M_SQRT2 1.41421356237309504880168872420969808
#define M_1_SQRT2 0.70710678118654752440084436210484904
#define M_EULER 0.57721566490153286060651209008240243
/* macros for constructing polynomials */
#define POLYNOM1(x, a) ((a)[1]*(x)+(a)[0])
#define POLYNOM2(x, a) (POLYNOM1((x),(a)+1)*(x)+(a)[0])
#define POLYNOM3(x, a) (POLYNOM2((x),(a)+1)*(x)+(a)[0])
#define POLYNOM4(x, a) (POLYNOM3((x),(a)+1)*(x)+(a)[0])
#define POLYNOM5(x, a) (POLYNOM4((x),(a)+1)*(x)+(a)[0])
#define POLYNOM6(x, a) (POLYNOM5((x),(a)+1)*(x)+(a)[0])
#define POLYNOM7(x, a) (POLYNOM6((x),(a)+1)*(x)+(a)[0])
#define POLYNOM8(x, a) (POLYNOM7((x),(a)+1)*(x)+(a)[0])
#define POLYNOM9(x, a) (POLYNOM8((x),(a)+1)*(x)+(a)[0])
#define POLYNOM10(x, a) (POLYNOM9((x),(a)+1)*(x)+(a)[0])
#define POLYNOM11(x, a) (POLYNOM10((x),(a)+1)*(x)+(a)[0])
#define POLYNOM12(x, a) (POLYNOM11((x),(a)+1)*(x)+(a)[0])
#define POLYNOM13(x, a) (POLYNOM12((x),(a)+1)*(x)+(a)[0])
#define M_LN_MAX_D (M_LN2 * DBL_MAX_EXP)
#define M_LN_MIN_D (M_LN2 * (DBL_MIN_EXP - 1))

67
lib/math/log.c Executable file
View File

@@ -0,0 +1,67 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <float.h>
#include <errno.h>
#include "localmath.h"
double
log(double x)
{
/* Algorithm and coefficients from:
"Software manual for the elementary functions"
by W.J. Cody and W. Waite, Prentice-Hall, 1980
*/
static double a[] = {
-0.64124943423745581147e2,
0.16383943563021534222e2,
-0.78956112887491257267e0
};
static double b[] = {
-0.76949932108494879777e3,
0.31203222091924532844e3,
-0.35667977739034646171e2,
1.0
};
double znum, zden, z, w;
int exponent;
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (x < 0) {
errno = EDOM;
return -HUGE_VAL;
}
else if (x == 0) {
errno = ERANGE;
return -HUGE_VAL;
}
if (x <= DBL_MAX) {
}
else return x; /* for infinity and Nan */
x = frexp(x, &exponent);
if (x > M_1_SQRT2) {
znum = (x - 0.5) - 0.5;
zden = x * 0.5 + 0.5;
}
else {
znum = x - 0.5;
zden = znum * 0.5 + 0.5;
exponent--;
}
z = znum/zden; w = z * z;
x = z + z * w * (POLYNOM2(w,a)/POLYNOM3(w,b));
z = exponent;
x += z * (-2.121944400546905827679e-4);
return x + z * 0.693359375;
}

30
lib/math/log10.c Executable file
View File

@@ -0,0 +1,30 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <errno.h>
#include "localmath.h"
double
log10(double x)
{
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (x < 0) {
errno = EDOM;
return -HUGE_VAL;
}
else if (x == 0) {
errno = ERANGE;
return -HUGE_VAL;
}
return log(x) / M_LN10;
}

49
lib/math/modf.s Executable file
View File

@@ -0,0 +1,49 @@
#
.sect .text; .sect .rom; .sect .data; .sect .bss
.extern _modf
.sect .text
_modf:
#if __i386
push ebp
mov ebp, esp
push 12(ebp)
push 8(ebp)
push 1
push 4
call .cif8
mov eax, esp
push eax
call .fif8
pop ecx
mov edx, 16(ebp)
pop ecx
pop ebx
mov 0(edx), ecx
mov 4(edx), ebx
pop eax
pop edx
leave
ret
#else /* i86 */
push bp
mov bp, sp
lea bx, 4(bp)
mov cx, #8
call .loi
mov dx, #1
push dx
push dx
push dx
mov ax, #2
push ax
call .cif8
mov ax, sp
push ax
call .fif8
pop bx
mov bx, 12(bp)
mov cx, #8
call .sti
call .ret8
jmp .cret
#endif

54
lib/math/pow.c Executable file
View File

@@ -0,0 +1,54 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <float.h>
#include <errno.h>
#include "localmath.h"
double
pow(double x, double y)
{
/* Simple version for now. The Cody and Waite book has
a very complicated, much more precise version, but
this version has machine-dependent arrays A1 and A2,
and I don't know yet how to solve this ???
*/
double dummy;
int result_neg = 0;
if ((x == 0 && y == 0) ||
(x < 0 && modf(y, &dummy) != 0)) {
errno = EDOM;
return 0;
}
if (x == 0) return x;
if (x < 0) {
if (modf(y/2.0, &dummy) != 0) {
/* y was odd */
result_neg = 1;
}
x = -x;
}
x = log(x);
if (x < 0) {
x = -x;
y = -y;
}
/* Beware of overflow in the multiplication */
if (x > 1.0 && y > DBL_MAX/x) {
errno = ERANGE;
return result_neg ? -HUGE_VAL : HUGE_VAL;
}
x = exp(x * y);
return result_neg ? -x : x;
}

99
lib/math/sin.c Executable file
View File

@@ -0,0 +1,99 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <float.h>
#include <errno.h>
#include "localmath.h"
static double
sinus(double x, int cos_flag)
{
/* Algorithm and coefficients from:
"Software manual for the elementary functions"
by W.J. Cody and W. Waite, Prentice-Hall, 1980
*/
static double r[] = {
-0.16666666666666665052e+0,
0.83333333333331650314e-2,
-0.19841269841201840457e-3,
0.27557319210152756119e-5,
-0.25052106798274584544e-7,
0.16058936490371589114e-9,
-0.76429178068910467734e-12,
0.27204790957888846175e-14
};
double y;
int neg = 1;
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (x < 0) {
x = -x;
neg = -1;
}
if (cos_flag) {
neg = 1;
y = M_PI_2 + x;
}
else y = x;
/* ??? avoid loss of significance, if y is too large, error ??? */
y = y * M_1_PI + 0.5;
if (y >= DBL_MAX/M_PI) return 0.0;
/* Use extended precision to calculate reduced argument.
Here we used 12 bits of the mantissa for a1.
Also split x in integer part x1 and fraction part x2.
*/
#define A1 3.1416015625
#define A2 -8.908910206761537356617e-6
{
double x1, x2;
modf(y, &y);
if (modf(0.5*y, &x1)) neg = -neg;
if (cos_flag) y -= 0.5;
x2 = modf(x, &x1);
x = x1 - y * A1;
x += x2;
x -= y * A2;
#undef A1
#undef A2
}
if (x < 0) {
neg = -neg;
x = -x;
}
/* ??? avoid underflow ??? */
y = x * x;
x += x * y * POLYNOM7(y, r);
return neg==-1 ? -x : x;
}
double
sin(double x)
{
return sinus(x, 0);
}
double
cos(double x)
{
if (x < 0) x = -x;
return sinus(x, 1);
}

81
lib/math/sinh.c Executable file
View File

@@ -0,0 +1,81 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <float.h>
#include <errno.h>
#include "localmath.h"
static double
sinh_cosh(double x, int cosh_flag)
{
/* Algorithm and coefficients from:
"Software manual for the elementary functions"
by W.J. Cody and W. Waite, Prentice-Hall, 1980
*/
static double p[] = {
-0.35181283430177117881e+6,
-0.11563521196851768270e+5,
-0.16375798202630751372e+3,
-0.78966127417357099479e+0
};
static double q[] = {
-0.21108770058106271242e+7,
0.36162723109421836460e+5,
-0.27773523119650701167e+3,
1.0
};
int negative = x < 0;
double y = negative ? -x : x;
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (! cosh_flag && y <= 1.0) {
/* ??? check for underflow ??? */
y = y * y;
return x + x * y * POLYNOM3(y, p)/POLYNOM3(y,q);
}
if (y >= M_LN_MAX_D) {
/* exp(y) would cause overflow */
#define LNV 0.69316101074218750000e+0
#define VD2M1 0.52820835025874852469e-4
double w = y - LNV;
if (w < M_LN_MAX_D+M_LN2-LNV) {
x = exp(w);
x += VD2M1 * x;
}
else {
errno = ERANGE;
x = HUGE_VAL;
}
}
else {
double z = exp(y);
x = 0.5 * (z + (cosh_flag ? 1.0 : -1.0)/z);
}
return negative ? -x : x;
}
double
sinh(double x)
{
return sinh_cosh(x, 0);
}
double
cosh(double x)
{
if (x < 0) x = -x;
return sinh_cosh(x, 1);
}

43
lib/math/sqrt.c Executable file
View File

@@ -0,0 +1,43 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <float.h>
#include <errno.h>
#define NITER 5
double
sqrt(double x)
{
int exponent;
double val;
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (x <= 0) {
if (x < 0) errno = EDOM;
return 0;
}
if (x > DBL_MAX) return x; /* for infinity */
val = frexp(x, &exponent);
if (exponent & 1) {
exponent--;
val *= 2;
}
val = ldexp(val + 1.0, exponent/2 - 1);
/* was: val = (val + 1.0)/2.0; val = ldexp(val, exponent/2); */
for (exponent = NITER - 1; exponent >= 0; exponent--) {
val = (val + x / val) / 2.0;
}
return val;
}

76
lib/math/tan.c Executable file
View File

@@ -0,0 +1,76 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <math.h>
#include <float.h>
#include <errno.h>
#include "localmath.h"
double
tan(double x)
{
/* Algorithm and coefficients from:
"Software manual for the elementary functions"
by W.J. Cody and W. Waite, Prentice-Hall, 1980
*/
int negative = x < 0;
int invert = 0;
double y;
static double p[] = {
1.0,
-0.13338350006421960681e+0,
0.34248878235890589960e-2,
-0.17861707342254426711e-4
};
static double q[] = {
1.0,
-0.46671683339755294240e+0,
0.25663832289440112864e-1,
-0.31181531907010027307e-3,
0.49819433993786512270e-6
};
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (negative) x = -x;
/* ??? avoid loss of significance, error if x is too large ??? */
y = x * M_2_PI + 0.5;
if (y >= DBL_MAX/M_PI_2) return 0.0;
/* Use extended precision to calculate reduced argument.
Here we used 12 bits of the mantissa for a1.
Also split x in integer part x1 and fraction part x2.
*/
#define A1 1.57080078125
#define A2 -4.454455103380768678308e-6
{
double x1, x2;
modf(y, &y);
if (modf(0.5*y, &x1)) invert = 1;
x2 = modf(x, &x1);
x = x1 - y * A1;
x += x2;
x -= y * A2;
#undef A1
#undef A2
}
/* ??? avoid underflow ??? */
y = x * x;
x += x * y * POLYNOM2(y, p+1);
y = POLYNOM4(y, q);
if (negative) x = -x;
return invert ? -y/x : x/y;
}

55
lib/math/tanh.c Executable file
View File

@@ -0,0 +1,55 @@
/*
* (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
/* $Header$ */
#include <float.h>
#include <math.h>
#include <errno.h>
#include "localmath.h"
double
tanh(double x)
{
/* Algorithm and coefficients from:
"Software manual for the elementary functions"
by W.J. Cody and W. Waite, Prentice-Hall, 1980
*/
static double p[] = {
-0.16134119023996228053e+4,
-0.99225929672236083313e+2,
-0.96437492777225469787e+0
};
static double q[] = {
0.48402357071988688686e+4,
0.22337720718962312926e+4,
0.11274474380534949335e+3,
1.0
};
int negative = x < 0;
if (__IsNan(x)) {
errno = EDOM;
return x;
}
if (negative) x = -x;
if (x >= 0.5*M_LN_MAX_D) {
x = 1.0;
}
#define LN3D2 0.54930614433405484570e+0 /* ln(3)/2 */
else if (x > LN3D2) {
x = 0.5 - 1.0/(exp(x+x)+1.0);
x += x;
}
else {
/* ??? avoid underflow ??? */
double g = x*x;
x += x * g * POLYNOM2(g, p)/POLYNOM3(g, q);
}
return negative ? -x : x;
}