home *** CD-ROM | disk | FTP | other *** search
/ Game Zone - 1,000+ Games / GAMEZONE.BIN / Programs / PALM / Oh-One / src / s_rint.c < prev    next >
C/C++ Source or Header  |  1997-08-16  |  3KB  |  101 lines

  1. // 15 August 1997, Rick Huebner:  Small changes made to adapt for MathLib
  2.  
  3. /* @(#)s_rint.c 5.1 93/09/24 */
  4. /*
  5.  * ====================================================
  6.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  7.  *
  8.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software is freely granted, provided that this notice
  11.  * is preserved.
  12.  * ====================================================
  13.  */
  14.  
  15. #if defined(LIBM_SCCS) && !defined(lint)
  16. static char rcsid[] = "$NetBSD: s_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $";
  17. #endif
  18.  
  19. /*
  20.  * rint(x)
  21.  * Return x rounded to integral value according to the prevailing
  22.  * rounding mode.
  23.  * Method:
  24.  *    Using floating addition.
  25.  * Exception:
  26.  *    Inexact flag raised if x not equal to rint(x).
  27.  */
  28.  
  29. #include "math.h"
  30. #include "math_private.h"
  31.  
  32. #ifdef _NO_STATIC_ARRAYS_
  33. #ifdef __STDC__
  34. static const double
  35. #else
  36. static double
  37. #endif
  38. TWO52[2]={
  39.   4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
  40.  -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
  41. };
  42. #endif    // _NO_STATIC_ARRAYS_
  43.  
  44. #ifdef __STDC__
  45.     double __rint(double x)
  46. #else
  47.     double __rint(x)
  48.     double x;
  49. #endif
  50. {
  51.     double TWO52[2];
  52.     int32_t i0,j0,sx;
  53.     u_int32_t i,i1;
  54.     double w,t;
  55.     
  56.     TWO52[0] =  4.50359962737049600000e+15; /* 0x43300000, 0x00000000 */
  57.     TWO52[1] = -4.50359962737049600000e+15; /* 0xC3300000, 0x00000000 */
  58.     
  59.     EXTRACT_WORDS(i0,i1,x);
  60.     sx = (i0>>31)&1;
  61.     j0 = ((i0>>20)&0x7ff)-0x3ff;
  62.     if(j0<20) {
  63.         if(j0<0) {
  64.         if(((i0&0x7fffffff)|i1)==0) return x;
  65.         i1 |= (i0&0x0fffff);
  66.         i0 &= 0xfffe0000;
  67.         i0 |= ((i1|-i1)>>12)&0x80000;
  68.         SET_HIGH_WORD(x,i0);
  69.             w = TWO52[sx]+x;
  70.             t =  w-TWO52[sx];
  71.         GET_HIGH_WORD(i0,t);
  72.         SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
  73.             return t;
  74.         } else {
  75.         i = (0x000fffff)>>j0;
  76.         if(((i0&i)|i1)==0) return x; /* x is integral */
  77.         i>>=1;
  78.         if(((i0&i)|i1)!=0) {
  79.             if(j0==19) i1 = 0x40000000; else
  80.             i0 = (i0&(~i))|((0x20000)>>j0);
  81.         }
  82.         }
  83.     } else if (j0>51) {
  84.         if(j0==0x400) return x+x;    /* inf or NaN */
  85.         else return x;        /* x is integral */
  86.     } else {
  87.         i = ((u_int32_t)(0xffffffff))>>(j0-20);
  88.         if((i1&i)==0) return x;    /* x is integral */
  89.         i>>=1;
  90.         if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
  91.     }
  92.     INSERT_WORDS(x,i0,i1);
  93.     w = TWO52[sx]+x;
  94.     return w-TWO52[sx];
  95. }
  96. weak_alias (__rint, rint)
  97. #ifdef NO_LONG_DOUBLE
  98. strong_alias (__rint, __rintl)
  99. weak_alias (__rint, rintl)
  100. #endif
  101.