home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 Mobile / Chip_Mobile_2001.iso / palm / hobby / palmoon / palmoon.EXE / s_round.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-16  |  2.3 KB  |  100 lines

  1. // 15 August 1997, Rick Huebner:  Small changes made to adapt for MathLib
  2.  
  3. /* Round double to integer away from zero.
  4.    Copyright (C) 1997 Free Software Foundation, Inc.
  5.    This file is part of the GNU C Library.
  6.    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
  7.  
  8.    The GNU C Library is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU Library General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    The GNU C Library is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    Library General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU Library General Public
  19.    License along with the GNU C Library; see the file COPYING.LIB.  If not,
  20.    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  21.    Boston, MA 02111-1307, USA.  */
  22.  
  23. #include "math.h"
  24.  
  25. #include "math_private.h"
  26.  
  27.  
  28. static const double huge = 1.0e300;
  29.  
  30.  
  31. double
  32. __round (double x)
  33. {
  34.   int32_t i0, j0;
  35.   u_int32_t i1;
  36.  
  37.   EXTRACT_WORDS (i0, i1, x);
  38.   j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
  39.   if (j0 < 20)
  40.     {
  41.       if (j0 < 0)
  42.     {
  43.       if (huge + x > 0.0)
  44.         {
  45.           i0 &= 0x80000000;
  46.           if (j0 == -1)
  47.         i0 |= 0x3ff00000;
  48.           i1 = 0;
  49.         }
  50.     }
  51.       else
  52.     {
  53.       u_int32_t i = 0x000fffff >> j0;
  54.       if (((i0 & i) | i1) == 0)
  55.         /* X is integral.  */
  56.         return x;
  57.       if (huge + x > 0.0)
  58.         {
  59.           /* Raise inexact if x != 0.  */
  60.           i0 += 0x00080000 >> j0;
  61.           i0 &= ~i;
  62.           i1 = 0;
  63.         }
  64.     }
  65.     }
  66.   else if (j0 > 51)
  67.     {
  68.       if (j0 == 0x400)
  69.     /* Inf or NaN.  */
  70.     return x + x;
  71.       else
  72.     return x;
  73.     }
  74.   else
  75.     {
  76.       u_int32_t i = 0xffffffff >> (j0 - 20);
  77.       if ((i1 & i) == 0)
  78.     /* X is integral.  */
  79.     return x;
  80.  
  81.       if (huge + x > 0.0)
  82.     {
  83.       /* Raise inexact if x != 0.  */
  84.       u_int32_t j = i1 + (1 << (51 - j0));
  85.       if (j < i1)
  86.         i0 += 1;
  87.       i1 = j;
  88.     }
  89.       i1 &= ~i;
  90.     }
  91.  
  92.   INSERT_WORDS (x, i0, i1);
  93.   return x;
  94. }
  95. weak_alias (__round, round)
  96. #ifdef NO_LONG_DOUBLE
  97. strong_alias (__round, __roundl)
  98. weak_alias (__round, roundl)
  99. #endif
  100.