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

  1. /* @(#)s_floor.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_floor.c,v 1.8 1995/05/10 20:47:20 jtc Exp $";
  15. #endif
  16.  
  17. /*
  18.  * floor(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 floor(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 __floor(double x)
  37. #else
  38.     double __floor(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=i1=0;}
  50.             else if(((i0&0x7fffffff)|i1)!=0)
  51.             { i0=0xbff00000;i1=0;}
  52.         }
  53.         } else {
  54.         i = (0x000fffff)>>j0;
  55.         if(((i0&i)|i1)==0) return x; /* x is integral */
  56.         if(huge+x>0.0) {    /* raise inexact flag */
  57.             if(i0<0) i0 += (0x00100000)>>j0;
  58.             i0 &= (~i); i1=0;
  59.         }
  60.         }
  61.     } else if (j0>51) {
  62.         if(j0==0x400) return x+x;    /* inf or NaN */
  63.         else return x;        /* x is integral */
  64.     } else {
  65.         i = ((u_int32_t)(0xffffffff))>>(j0-20);
  66.         if((i1&i)==0) return x;    /* x is integral */
  67.         if(huge+x>0.0) {         /* raise inexact flag */
  68.         if(i0<0) {
  69.             if(j0==20) i0+=1;
  70.             else {
  71.             j = i1+(1<<(52-j0));
  72.             if(j<i1) i0 +=1 ;     /* got a carry */
  73.             i1=j;
  74.             }
  75.         }
  76.         i1 &= (~i);
  77.         }
  78.     }
  79.     INSERT_WORDS(x,i0,i1);
  80.     return x;
  81. }
  82. weak_alias (__floor, floor)
  83. #ifdef NO_LONG_DOUBLE
  84. strong_alias (__floor, __floorl)
  85. weak_alias (__floor, floorl)
  86. #endif
  87.