A bit more BeOS compatible math.h functions.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6962 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1e37a9ac80
commit
f7f6185398
@ -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 <sys/types.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
@ -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 <ktypes.h>
|
||||
#include <math.h>
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
@ -83,7 +83,9 @@
|
||||
* from decimal to binary accurately enough to produce the hexadecimal values
|
||||
* shown.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#include <mathimpl.h>
|
||||
|
||||
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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user