POK
|
00001 /* 00002 * POK header 00003 * 00004 * The following file is a part of the POK project. Any modification should 00005 * made according to the POK licence. You CANNOT use this file or a part of 00006 * this file is this part of a file for your own project 00007 * 00008 * For more information on the POK licence, please see our LICENCE FILE 00009 * 00010 * Please follow the coding guidelines described in doc/CODING_GUIDELINES 00011 * 00012 * Copyright (c) 2007-2009 POK team 00013 * 00014 * Created by julien on Fri Jan 30 14:41:34 2009 00015 */ 00016 00017 /* @(#)s_floor.c 5.1 93/09/24 */ 00018 /* 00019 * ==================================================== 00020 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 00021 * 00022 * Developed at SunPro, a Sun Microsystems, Inc. business. 00023 * Permission to use, copy, modify, and distribute this 00024 * software is freely granted, provided that this notice 00025 * is preserved. 00026 * ==================================================== 00027 */ 00028 00029 /* 00030 * floor(x) 00031 * Return x rounded toward -inf to integral value 00032 * Method: 00033 * Bit twiddling. 00034 * Exception: 00035 * Inexact flag raised if x not equal to floor(x). 00036 */ 00037 00038 #ifdef POK_NEEDS_LIBMATH 00039 00040 #include "math_private.h" 00041 00042 static const double huge = 1.0e300; 00043 00044 double 00045 floor(double x) 00046 { 00047 int32_t i0,i1,jj0; 00048 uint32_t i,j; 00049 EXTRACT_WORDS(i0,i1,x); 00050 jj0 = ((i0>>20)&0x7ff)-0x3ff; 00051 if(jj0<20) { 00052 if(jj0<0) { /* raise inexact if x != 0 */ 00053 if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ 00054 if(i0>=0) {i0=i1=0;} 00055 else if(((i0&0x7fffffff)|i1)!=0) 00056 { i0=0xbff00000;i1=0;} 00057 } 00058 } else { 00059 i = (0x000fffff)>>jj0; 00060 if(((i0&i)|i1)==0) return x; /* x is integral */ 00061 if(huge+x>0.0) { /* raise inexact flag */ 00062 if(i0<0) i0 += (0x00100000)>>jj0; 00063 i0 &= (~i); i1=0; 00064 } 00065 } 00066 } else if (jj0>51) { 00067 if(jj0==0x400) return x+x; /* inf or NaN */ 00068 else return x; /* x is integral */ 00069 } else { 00070 i = ((uint32_t)(0xffffffff))>>(jj0-20); 00071 if((i1&i)==0) return x; /* x is integral */ 00072 if(huge+x>0.0) { /* raise inexact flag */ 00073 if(i0<0) { 00074 if(jj0==20) i0+=1; 00075 else { 00076 j = i1+(1<<(52-jj0)); 00077 if(j<(uint32_t)i1) i0 +=1 ; /* got a carry */ 00078 i1=j; 00079 } 00080 } 00081 i1 &= (~i); 00082 } 00083 } 00084 INSERT_WORDS(x,i0,i1); 00085 return x; 00086 } 00087 00088 #endif