base/math/s_floor.c

Go to the documentation of this file.
00001 #if !defined(__ppc__)
00002 /* @(#)s_floor.c 5.1 93/09/24 */
00003 /*
00004  * ====================================================
00005  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
00006  *
00007  * Developed at SunPro, a Sun Microsystems, Inc. business.
00008  * Permission to use, copy, modify, and distribute this
00009  * software is freely granted, provided that this notice 
00010  * is preserved.
00011  * ====================================================
00012  */
00013 
00014 #if defined(LIBM_SCCS) && !defined(lint)
00015 static char rcsid[] = "$NetBSD: s_floor.c,v 1.8 1995/05/10 20:47:20 jtc Exp $";
00016 #endif
00017 
00018 /*
00019  * floor(x)
00020  * Return x rounded toward -inf to integral value
00021  * Method:
00022  *  Bit twiddling.
00023  * Exception:
00024  *  Inexact flag raised if x not equal to floor(x).
00025  */
00026 
00027 #include "math.h"
00028 #include "mathP.h"
00029 
00030 #ifdef __STDC__
00031 static const double huge = 1.0e300;
00032 #else
00033 static double huge = 1.0e300;
00034 #endif
00035 
00036 #ifdef __STDC__
00037     double floor(double x)
00038 #else
00039     double floor(x)
00040     double x;
00041 #endif
00042 {
00043     int32_t i0,i1,j0;
00044     u_int32_t i,j;
00045     EXTRACT_WORDS(i0,i1,x);
00046     j0 = ((i0>>20)&0x7ff)-0x3ff;
00047     if(j0<20) {
00048         if(j0<0) {  /* raise inexact if x != 0 */
00049         if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
00050             if(i0>=0) {i0=i1=0;} 
00051             else if(((i0&0x7fffffff)|i1)!=0)
00052             { i0=0xbff00000;i1=0;}
00053         }
00054         } else {
00055         i = (0x000fffff)>>j0;
00056         if(((i0&i)|i1)==0) return x; /* x is integral */
00057         if(huge+x>0.0) {    /* raise inexact flag */
00058             if(i0<0) i0 += (0x00100000)>>j0;
00059             i0 &= (~i); i1=0;
00060         }
00061         }
00062     } else if (j0>51) {
00063         if(j0==0x400) return x+x;   /* inf or NaN */
00064         else return x;      /* x is integral */
00065     } else {
00066         i = ((u_int32_t)(0xffffffff))>>(j0-20);
00067         if((i1&i)==0) return x; /* x is integral */
00068         if(huge+x>0.0) {        /* raise inexact flag */
00069         if(i0<0) {
00070             if(j0==20) i0+=1; 
00071             else {
00072             j = i1+(1<<(52-j0));
00073             if(j<i1) i0 +=1 ;   /* got a carry */
00074             i1=j;
00075             }
00076         }
00077         i1 &= (~i);
00078         }
00079     }
00080     INSERT_WORDS(x,i0,i1);
00081     return x;
00082 }
00083 #endif /* !__ppc__ */

Generated on Tue Feb 2 17:46:05 2010 for RTAI API by  doxygen 1.4.7