From dfd3dc317016f901a6e7b8df6b9b831a2a8d2b6b Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Fri, 27 Aug 2004 13:49:17 +0000 Subject: [PATCH] - Replaced the rint() and rintf() functions with the fdlibm code. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14719 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/changes | 2 ++ library/math_headers.h | 29 ++++++++++++++++- library/math_rint.c | 74 ++++++++++++++++++++++++++++++++++++++++-- library/math_rintf.c | 67 ++++++++++++++++++++++++++++++++++++-- library/releasenotes | 3 +- 5 files changed, 169 insertions(+), 6 deletions(-) diff --git a/library/changes b/library/changes index e8cc7d2..8e026ff 100644 --- a/library/changes +++ b/library/changes @@ -5,6 +5,8 @@ c.lib 1.174 (27.8.2004) - Merged fdlibm 5.3 changes with __kernel_tan(), __exp() and __pow() functions. +- Replaced the rint() and rintf() functions with the fdlibm code. + c.lib 1.173 (25.8.2004) diff --git a/library/math_headers.h b/library/math_headers.h index 04a566b..3a446d2 100644 --- a/library/math_headers.h +++ b/library/math_headers.h @@ -1,5 +1,5 @@ /* - * $Id: math_headers.h,v 1.3 2004-08-21 18:57:40 obarthel Exp $ + * $Id: math_headers.h,v 1.4 2004-08-27 13:49:17 obarthel Exp $ * * :ts=4 * @@ -148,6 +148,33 @@ do { \ (d) = sl_u.value; \ } while (0) +/* A union which permits us to convert between a float and a 32 bit + int. */ + +typedef union +{ + float value; + unsigned int word; +} ieee_float_shape_type; + +/* Get a 32 bit int from a float. */ + +#define GET_FLOAT_WORD(i,d) \ +do { \ + ieee_float_shape_type gf_u; \ + gf_u.value = (d); \ + (i) = gf_u.word; \ +} while (0) + +/* Set a float from a 32 bit int. */ + +#define SET_FLOAT_WORD(d,i) \ +do { \ + ieee_float_shape_type sf_u; \ + sf_u.word = (i); \ + (d) = sf_u.value; \ +} while (0) + extern double __kernel_cos(double x, double y); extern double __kernel_sin(double x, double y, int iy); extern int __rem_pio2(double x, double *y); diff --git a/library/math_rint.c b/library/math_rint.c index 0dccd76..d047a77 100755 --- a/library/math_rint.c +++ b/library/math_rint.c @@ -1,5 +1,5 @@ /* - * $Id: math_rint.c,v 1.2 2004-08-07 09:15:32 obarthel Exp $ + * $Id: math_rint.c,v 1.3 2004-08-27 13:49:17 obarthel Exp $ * * :ts=4 * @@ -54,6 +54,10 @@ /****************************************************************************/ +#if defined(IEEE_FLOATING_POINT_SUPPORT) || defined(M68881_FLOATING_POINT_SUPPORT) + +/****************************************************************************/ + double rint(double x) { @@ -62,5 +66,71 @@ rint(double x) /****************************************************************************/ -#endif /* FLOATING_POINT_SUPPORT */ +#endif /* IEEE_FLOATING_POINT_SUPPORT || M68881_FLOATING_POINT_SUPPORT */ +/****************************************************************************/ + +#if defined(PPC_FLOATING_POINT_SUPPORT) + +/****************************************************************************/ + +static const double +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +double +rint(double x) +{ + int i0,j0,sx; + unsigned i,i1; + double w,t; + GET_HIGH_WORD(i0,x); + sx = (i0>>31)&1; + GET_LOW_WORD(i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { + if(((i0&0x7fffffff)|i1)==0) return x; + i1 |= (i0&0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1|-i1)>>12)&0x80000; + SET_HIGH_WORD(x,i0); + w = TWO52[sx]+x; + t = w-TWO52[sx]; + GET_HIGH_WORD(i0,t); + SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + i>>=1; + if(((i0&i)|i1)!=0) { + if(j0==19) i1 = 0x40000000; else + i0 = (i0&(~i))|((0x20000)>>j0); + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((unsigned)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + i>>=1; + if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); + } + + SET_HIGH_WORD(x,i0); + SET_LOW_WORD(x,i1); + w = TWO52[sx]+x; + return w-TWO52[sx]; +} + +/****************************************************************************/ + +#endif /* PPC_FLOATING_POINT_SUPPORT */ + +/****************************************************************************/ + +#endif /* FLOATING_POINT_SUPPORT */ diff --git a/library/math_rintf.c b/library/math_rintf.c index 1caacca..8800423 100755 --- a/library/math_rintf.c +++ b/library/math_rintf.c @@ -1,5 +1,5 @@ /* - * $Id: math_rintf.c,v 1.1 2004-08-07 09:15:32 obarthel Exp $ + * $Id: math_rintf.c,v 1.2 2004-08-27 13:49:17 obarthel Exp $ * * :ts=4 * @@ -54,6 +54,10 @@ /****************************************************************************/ +#if defined(IEEE_FLOATING_POINT_SUPPORT) || defined(M68881_FLOATING_POINT_SUPPORT) + +/****************************************************************************/ + float rintf(float x) { @@ -62,5 +66,64 @@ rintf(float x) /****************************************************************************/ -#endif /* FLOATING_POINT_SUPPORT */ +#endif /* IEEE_FLOATING_POINT_SUPPORT || M68881_FLOATING_POINT_SUPPORT */ +/****************************************************************************/ + +#if defined(PPC_FLOATING_POINT_SUPPORT) + +/****************************************************************************/ + +/* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. */ + +/****************************************************************************/ + +static const float +TWO23[2]={ + 8.3886080000e+06, /* 0x4b000000 */ + -8.3886080000e+06, /* 0xcb000000 */ +}; + +float +rintf(float x) +{ + int i0,j0,sx; + unsigned int i,i1; + float w,t; + GET_FLOAT_WORD(i0,x); + sx = (i0>>31)&1; + j0 = ((i0>>23)&0xff)-0x7f; + if(j0<23) { + if(j0<0) { + if((i0&0x7fffffff)==0) return x; + i1 = (i0&0x07fffff); + i0 &= 0xfff00000; + i0 |= ((i1|-i1)>>9)&0x400000; + SET_FLOAT_WORD(x,i0); + w = TWO23[sx]+x; + t = w-TWO23[sx]; + GET_FLOAT_WORD(i0,t); + SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31)); + return t; + } else { + i = (0x007fffff)>>j0; + if((i0&i)==0) return x; /* x is integral */ + i>>=1; + if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0); + } + } else { + if(j0==0x80) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } + SET_FLOAT_WORD(x,i0); + w = TWO23[sx]+x; + return w-TWO23[sx]; +} + +/****************************************************************************/ + +#endif /* PPC_FLOATING_POINT_SUPPORT */ + +/****************************************************************************/ + +#endif /* FLOATING_POINT_SUPPORT */ diff --git a/library/releasenotes b/library/releasenotes index d852cfc..dd823c0 100644 --- a/library/releasenotes +++ b/library/releasenotes @@ -3,4 +3,5 @@ c.lib 1.174 (27.8.2004) - atan2() did not work correctly. Please rebuild any code that uses it. -- tan(), exp() and pow() now should return more accurate results. +- tan(), exp(), pow(), rint() and rintf() now should return more + accurate results.