base/math/s_ceil.c

Go to the documentation of this file.
00001 #if !defined(__ppc__)
00002 /* @(#)s_ceil.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_ceil.c,v 1.8 1995/05/10 20:46:53 jtc Exp $";
00016 #endif
00017 
00018 /*
00019  * ceil(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 ceil(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 ceil(double x)
00038 #else
00039     double ceil(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=0x80000000;i1=0;} 
00051             else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
00052         }
00053         } else {
00054         i = (0x000fffff)>>j0;
00055         if(((i0&i)|i1)==0) return x; /* x is integral */
00056         if(huge+x>0.0) {    /* raise inexact flag */
00057             if(i0>0) i0 += (0x00100000)>>j0;
00058             i0 &= (~i); i1=0;
00059         }
00060         }
00061     } else if (j0>51) {
00062         if(j0==0x400) return x+x;   /* inf or NaN */
00063         else return x;      /* x is integral */
00064     } else {
00065         i = ((u_int32_t)(0xffffffff))>>(j0-20);
00066         if((i1&i)==0) return x; /* x is integral */
00067         if(huge+x>0.0) {        /* raise inexact flag */
00068         if(i0>0) {
00069             if(j0==20) i0+=1; 
00070             else {
00071             j = i1 + (1<<(52-j0));
00072             if(j<i1) i0+=1; /* got a carry */
00073             i1 = j;
00074             }
00075         }
00076         i1 &= (~i);
00077         }
00078     }
00079     INSERT_WORDS(x,i0,i1);
00080     return x;
00081 }
00082 #endif /* !__ppc__ */

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