From f7f6185398aed230d42a8353eb909cc43f42adb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 13 Mar 2004 18:48:55 +0000 Subject: [PATCH] A bit more BeOS compatible math.h functions. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6962 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../libroot/posix/math/arch/ppc/isinf.c | 63 +++++++-- .../libroot/posix/math/arch/x86/isinf.c | 60 ++++++--- src/kernel/libroot/posix/math/cabs.c | 122 ++++++++++-------- src/kernel/libroot/posix/math/fmod.c | 71 +--------- 4 files changed, 163 insertions(+), 153 deletions(-) diff --git a/src/kernel/libroot/posix/math/arch/ppc/isinf.c b/src/kernel/libroot/posix/math/arch/ppc/isinf.c index b060e9304d..e11232cf3b 100644 --- a/src/kernel/libroot/posix/math/arch/ppc/isinf.c +++ b/src/kernel/libroot/posix/math/arch/ppc/isinf.c @@ -1,4 +1,5 @@ -/* Copyright (c) 1991, 1993 +/*- + * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,20 +29,19 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD: src/lib/libc/i386/gen/isinf.c,v 1.6 1999/08/27 23:59:21 peter Exp $ */ -#include + #include -/* ToDo: on BeOS/x86, these are defined as __isnan(), and __isinf() - the - * isnan()/isinf() are only macros - we will have to reflect this here. - */ -int isnan(double); -int isinf(double); +// double + int -isnan(double d) +__isnan(double d) { register struct IEEEdp { unsigned manl : 32; @@ -55,14 +55,51 @@ isnan(double d) int -isinf(double d) +__isinf(double d) { register struct IEEEdp { - u_int manl : 32; - u_int manh : 20; - u_int exp : 11; - u_int sign : 1; + unsigned manl : 32; + unsigned manh : 20; + unsigned exp : 11; + unsigned sign : 1; } *p = (struct IEEEdp *)&d; return p->exp == 2047 && !p->manh && !p->manl; } + + +// #pragma mark - +// float + + +int +__isnanf(float f) +{ + // ToDo: fix implementation! + return __isnan((double)f); +} + + +int +__isinff(float f) +{ + return __isinf((double)f); +} + + +// #pragma mark - +// long double + + +int +__isnanl(long double d) +{ + return __isnan((double)d); +} + + +int +__isinfl(long double d) +{ + return __isinf((double)d); +} diff --git a/src/kernel/libroot/posix/math/arch/x86/isinf.c b/src/kernel/libroot/posix/math/arch/x86/isinf.c index ff32fbd7de..e11232cf3b 100644 --- a/src/kernel/libroot/posix/math/arch/x86/isinf.c +++ b/src/kernel/libroot/posix/math/arch/x86/isinf.c @@ -33,22 +33,15 @@ * $FreeBSD: src/lib/libc/i386/gen/isinf.c,v 1.6 1999/08/27 23:59:21 peter Exp $ */ -#if defined(LIBC_RCS) && !defined(lint) -static const char rcsid[] = "$FreeBSD: src/lib/libc/i386/gen/isinf.c,v 1.6 1999/08/27 23:59:21 peter Exp $"; -#endif /* LIBC_RCS and not lint */ -#include #include -/* ToDo: on BeOS/x86, these are defined as __isnan(), and __isinf() - the - * isnan()/isinf() are only macros - we will have to reflect this here. - */ -int isnan(double); -int isinf(double); +// double + int -isnan(double d) +__isnan(double d) { register struct IEEEdp { unsigned manl : 32; @@ -62,14 +55,51 @@ isnan(double d) int -isinf(double d) +__isinf(double d) { register struct IEEEdp { - u_int manl : 32; - u_int manh : 20; - u_int exp : 11; - u_int sign : 1; + unsigned manl : 32; + unsigned manh : 20; + unsigned exp : 11; + unsigned sign : 1; } *p = (struct IEEEdp *)&d; return p->exp == 2047 && !p->manh && !p->manl; } + + +// #pragma mark - +// float + + +int +__isnanf(float f) +{ + // ToDo: fix implementation! + return __isnan((double)f); +} + + +int +__isinff(float f) +{ + return __isinf((double)f); +} + + +// #pragma mark - +// long double + + +int +__isnanl(long double d) +{ + return __isnan((double)d); +} + + +int +__isinfl(long double d) +{ + return __isinf((double)d); +} diff --git a/src/kernel/libroot/posix/math/cabs.c b/src/kernel/libroot/posix/math/cabs.c index 6301b35031..a9fd2dc80e 100644 --- a/src/kernel/libroot/posix/math/cabs.c +++ b/src/kernel/libroot/posix/math/cabs.c @@ -83,7 +83,9 @@ * from decimal to binary accurately enough to produce the hexadecimal values * shown. */ - + + +#include #include vc(r2p1hi, 2.4142135623730950345E0 ,8279,411a,ef32,99fc, 2, .9A827999FCEF32) @@ -95,72 +97,74 @@ ic(r2p1lo, 1.2537167179050217666E-16 , -53, 1.21165F626CDD5) ic(sqrt2, 1.4142135623730951455E0 , 0, 1.6A09E667F3BCD) #ifdef vccast -#define r2p1hi vccast(r2p1hi) -#define r2p1lo vccast(r2p1lo) -#define sqrt2 vccast(sqrt2) +# define r2p1hi vccast(r2p1hi) +# define r2p1lo vccast(r2p1lo) +# define sqrt2 vccast(sqrt2) #endif + double hypot(double x, double y) { - static double const zero=0; - static double const one=1; - static double const small=1.0E-18; /* fl(1+small)==1 */ - static int const ibig=30; /* fl(1+2**(2*ibig))==1 */ - double t; - double r; - int exp; + static double const zero = 0; + static double const one = 1; + static double const small = 1.0E-18; /* fl(1+small)==1 */ + static int const ibig = 30; /* fl(1+2**(2*ibig))==1 */ - if(finite(x)) { - if(finite(y)) { - x=copysign(x,one); - y=copysign(y,one); - if(y > x) { - t=x; x=y; y=t; - } - if(x == zero) return(zero); - if(y == zero) return(x); - exp= logb(x); - if(exp-(int)logb(y) > ibig ) { - /* raise inexact flag and return |x| */ - (void volatile)(one+small); - return(x); - } + if (finite(x)) { + if (finite(y)) { + double t; + double r; + int e; - /* start computing sqrt(x^2 + y^2) */ - r=x-y; - if(r>y) { /* x/y > 2 */ - r=x/y; - r=r+sqrt(one+r*r); - } else { /* 1 <= x/y <= 2 */ - r/=y; t=r*(r+2.0); - r+=t/(sqrt2+sqrt(2.0+t)); - r+=r2p1lo; r+=r2p1hi; - } + x = copysign(x, one); + y = copysign(y, one); + if (y > x) { + t = x; x = y; y = t; + } - r=y/r; - return(x+r); + if (x == zero) + return zero; + if (y == zero) + return x; - } + e = logb(x); + if (e - (int)logb(y) > ibig ) { + /* raise inexact flag and return |x| */ + (void volatile)(one + small); + return x; + } - else if(y==y) /* y is +-INF */ - return(copysign(y,one)); - else - return(y); /* y is NaN and x is finite */ + /* start computing sqrt(x^2 + y^2) */ + r = x - y; + if (r > y) { /* x/y > 2 */ + r = x / y; + r = r + sqrt(one + r*r); + } else { /* 1 <= x/y <= 2 */ + r /= y; + t = r * (r + 2.0); + r += t / (sqrt2 + sqrt(2.0 + t)); + r += r2p1lo; + r += r2p1hi; + } - } else if(x==x) { - return (copysign(x,one)); /* x is +-INF */ - } else if(finite(y)) { - return(x); /* x is NaN, y is finite */ -#if !defined(vax)&&!defined(tahoe) - } else if(y!=y) { - return(y); /* x and y is NaN */ -#endif /* !defined(vax)&&!defined(tahoe) */ - } else { - return(copysign(y,one)); /* y is INF */ - } + r = y / r; + return x + r; + } else if (y == y) { /* y is +-INF */ + return copysign(y, one); + } else + return y; /* y is NaN and x is finite */ + } else if (x == x) { + return copysign(x, one); /* x is +-INF */ + } else if (finite(y)) { + return x; /* x is NaN, y is finite */ + } else if (y != y) { + return y; /* x and y is NaN */ + } else + return copysign(y, one); /* y is INF */ } + /* CABS(Z) * RETURN THE ABSOLUTE VALUE OF THE COMPLEX NUMBER Z = X + iY * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS) @@ -174,17 +178,23 @@ hypot(double x, double y) * cabs(z) = hypot(x,y) . */ +// ToDo: complex functions are currently missing - BeOS doesn't have +// a header for them, but libroot.so seems to define all functions + +#if 0 double cabs(struct complex z) { - return hypot(z.x,z.y); + return hypot(z.x, z.y); } + double z_abs(struct complex const *z) { - return hypot(z->x,z->y); + return hypot(z->x, z->y); } +#endif /* A faster but less accurate version of cabs(x,y) */ #if 0 diff --git a/src/kernel/libroot/posix/math/fmod.c b/src/kernel/libroot/posix/math/fmod.c index bd716b721d..02f3b29082 100644 --- a/src/kernel/libroot/posix/math/fmod.c +++ b/src/kernel/libroot/posix/math/fmod.c @@ -59,19 +59,10 @@ * fmod(x,0), fmod(INF,y) are invalid operations and NaN is returned. * */ -#if !defined(vax) && !defined(tahoe) -extern int isnan(),finite(); -#endif /* !defined(vax) && !defined(tahoe) */ -extern double frexp(),ldexp(),fabs(); -#ifdef TEST_FMOD -static double -_fmod(x,y) -#else /* TEST_FMOD */ + double -fmod(x,y) -#endif /* TEST_FMOD */ -double x,y; +fmod(double x, double y) { int ir,iy; double r,w; @@ -93,61 +84,3 @@ double x,y; } return x >= (double)0 ? r : -r; } - -#ifdef TEST_FMOD -extern long random(); -extern double fmod(); - -#define NTEST 10000 -#define NCASES 3 - -static int nfail = 0; - -static void -doit(x,y) -double x,y; -{ - double ro = fmod(x,y),rn = _fmod(x,y); - if (ro != rn) { - (void)printf(" x = 0x%08.8x %08.8x (%24.16e)\n",x,x); - (void)printf(" y = 0x%08.8x %08.8x (%24.16e)\n",y,y); - (void)printf(" fmod = 0x%08.8x %08.8x (%24.16e)\n",ro,ro); - (void)printf("_fmod = 0x%08.8x %08.8x (%24.16e)\n",rn,rn); - (void)printf("\n"); - } -} - -main() -{ - register int i,cases; - double x,y; - - srandom(12345); - for (i = 0; i < NTEST; i++) { - x = (double)random(); - y = (double)random(); - for (cases = 0; cases < NCASES; cases++) { - switch (cases) { - case 0: - break; - case 1: - y = (double)1/y; break; - case 2: - x = (double)1/x; break; - default: - abort(); break; - } - doit(x,y); - doit(x,-y); - doit(-x,y); - doit(-x,-y); - } - } - if (nfail) - (void)printf("Number of failures: %d (out of a total of %d)\n", - nfail,NTEST*NCASES*4); - else - (void)printf("No discrepancies were found\n"); - exit(0); -} -#endif /* TEST_FMOD */