Initial revision
This commit is contained in:
97
lib/math/Makefile
Executable file
97
lib/math/Makefile
Executable 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
82
lib/math/asin.c
Executable 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
72
lib/math/atan.c
Executable 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
42
lib/math/atan2.c
Executable 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
20
lib/math/ceil.c
Executable 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
72
lib/math/exp.c
Executable 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
13
lib/math/fabs.c
Executable 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
20
lib/math/floor.c
Executable 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
34
lib/math/fmod.c
Executable 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
35
lib/math/frexp.s
Executable 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
14
lib/math/hugeval.c
Executable 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
11
lib/math/isnan.c
Executable 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
55
lib/math/ldexp.c
Executable 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
42
lib/math/localmath.h
Executable 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
67
lib/math/log.c
Executable 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
30
lib/math/log10.c
Executable 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
49
lib/math/modf.s
Executable 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
54
lib/math/pow.c
Executable 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
99
lib/math/sin.c
Executable 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
81
lib/math/sinh.c
Executable 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
43
lib/math/sqrt.c
Executable 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
76
lib/math/tan.c
Executable 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
55
lib/math/tanh.c
Executable 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;
|
||||
}
|
||||
Reference in New Issue
Block a user