home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 Mobile / Chip_Mobile_2001.iso / palm / hobby / palmoon / palmoon.EXE / s_ceil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-05  |  2.0 KB  |  86 lines

  1. /* @(#)s_ceil.c 5.1 93/09/24 */
  2. /*
  3.  * ====================================================
  4.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  5.  *
  6.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software is freely granted, provided that this notice
  9.  * is preserved.
  10.  * ====================================================
  11.  */
  12.  
  13. #if defined(LIBM_SCCS) && !defined(lint)
  14. static char rcsid[] = "$NetBSD: s_ceil.c,v 1.8 1995/05/10 20:46:53 jtc Exp $";
  15. #endif
  16.  
  17. /*
  18.  * ceil(x)
  19.  * Return x rounded toward -inf to integral value
  20.  * Method:
  21.  *    Bit twiddling.
  22.  * Exception:
  23.  *    Inexact flag raised if x not equal to ceil(x).
  24.  */
  25.  
  26. #include "math.h"
  27. #include "math_private.h"
  28.  
  29. #ifdef __STDC__
  30. static const double huge = 1.0e300;
  31. #else
  32. static double huge = 1.0e300;
  33. #endif
  34.  
  35. #ifdef __STDC__
  36.     double __ceil(double x)
  37. #else
  38.     double __ceil(x)
  39.     double x;
  40. #endif
  41. {
  42.     int32_t i0,i1,j0;
  43.     u_int32_t i,j;
  44.     EXTRACT_WORDS(i0,i1,x);
  45.     j0 = ((i0>>20)&0x7ff)-0x3ff;
  46.     if(j0<20) {
  47.         if(j0<0) {     /* raise inexact if x != 0 */
  48.         if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
  49.             if(i0<0) {i0=0x80000000;i1=0;}
  50.             else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
  51.         }
  52.         } else {
  53.         i = (0x000fffff)>>j0;
  54.         if(((i0&i)|i1)==0) return x; /* x is integral */
  55.         if(huge+x>0.0) {    /* raise inexact flag */
  56.             if(i0>0) i0 += (0x00100000)>>j0;
  57.             i0 &= (~i); i1=0;
  58.         }
  59.         }
  60.     } else if (j0>51) {
  61.         if(j0==0x400) return x+x;    /* inf or NaN */
  62.         else return x;        /* x is integral */
  63.     } else {
  64.         i = ((u_int32_t)(0xffffffff))>>(j0-20);
  65.         if((i1&i)==0) return x;    /* x is integral */
  66.         if(huge+x>0.0) {         /* raise inexact flag */
  67.         if(i0>0) {
  68.             if(j0==20) i0+=1;
  69.             else {
  70.             j = i1 + (1<<(52-j0));
  71.             if(j<i1) i0+=1;    /* got a carry */
  72.             i1 = j;
  73.             }
  74.         }
  75.         i1 &= (~i);
  76.         }
  77.     }
  78.     INSERT_WORDS(x,i0,i1);
  79.     return x;
  80. }
  81. weak_alias (__ceil, ceil)
  82. #ifdef NO_LONG_DOUBLE
  83. strong_alias (__ceil, __ceill)
  84. weak_alias (__ceil, ceill)
  85. #endif
  86.