base/math/s_rint.c

Go to the documentation of this file.
00001 #if !defined(__ppc__) 00002 /* @(#)s_rint.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_rint.c,v 1.8 1995/05/10 20:48:04 jtc Exp $"; 00016 #endif 00017 00018 /* 00019 * rint(x) 00020 * Return x rounded to integral value according to the prevailing 00021 * rounding mode. 00022 * Method: 00023 * Using floating addition. 00024 * Exception: 00025 * Inexact flag raised if x not equal to rint(x). 00026 */ 00027 00028 #include "math.h" 00029 #include "mathP.h" 00030 00031 #ifdef __STDC__ 00032 static const double 00033 #else 00034 static double 00035 #endif 00036 TWO52[2]={ 00037 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ 00038 -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ 00039 }; 00040 00041 #ifdef __STDC__ 00042 double rint(double x) 00043 #else 00044 double rint(x) 00045 double x; 00046 #endif 00047 { 00048 int32_t i0,j0,sx; 00049 u_int32_t i,i1; 00050 double w,t; 00051 EXTRACT_WORDS(i0,i1,x); 00052 sx = (i0>>31)&1; 00053 j0 = ((i0>>20)&0x7ff)-0x3ff; 00054 if(j0<20) { 00055 if(j0<0) { 00056 if(((i0&0x7fffffff)|i1)==0) return x; 00057 i1 |= (i0&0x0fffff); 00058 i0 &= 0xfffe0000; 00059 i0 |= ((i1|-i1)>>12)&0x80000; 00060 SET_HIGH_WORD(x,i0); 00061 w = TWO52[sx]+x; 00062 t = w-TWO52[sx]; 00063 GET_HIGH_WORD(i0,t); 00064 SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31)); 00065 return t; 00066 } else { 00067 i = (0x000fffff)>>j0; 00068 if(((i0&i)|i1)==0) return x; /* x is integral */ 00069 i>>=1; 00070 if(((i0&i)|i1)!=0) { 00071 if(j0==19) i1 = 0x40000000; else 00072 i0 = (i0&(~i))|((0x20000)>>j0); 00073 } 00074 } 00075 } else if (j0>51) { 00076 if(j0==0x400) return x+x; /* inf or NaN */ 00077 else return x; /* x is integral */ 00078 } else { 00079 i = ((u_int32_t)(0xffffffff))>>(j0-20); 00080 if((i1&i)==0) return x; /* x is integral */ 00081 i>>=1; 00082 if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); 00083 } 00084 INSERT_WORDS(x,i0,i1); 00085 w = TWO52[sx]+x; 00086 return w-TWO52[sx]; 00087 } 00088 #endif /* !__ppc__ */

Generated on Thu Nov 20 11:49:52 2008 for RTAI API by doxygen 1.3.8