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_ceil.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 /* 00031 * ceil(x) 00032 * Return x rounded toward -inf to integral value 00033 * Method: 00034 * Bit twiddling. 00035 * Exception: 00036 * Inexact flag raised if x not equal to ceil(x). 00037 */ 00038 00039 #ifdef POK_NEEDS_LIBMATH 00040 00041 #include <libm.h> 00042 #include "math_private.h" 00043 00044 static const double huge = 1.0e300; 00045 00046 double 00047 ceil(double x) 00048 { 00049 int32_t i0,i1,jj0; 00050 uint32_t i,j; 00051 EXTRACT_WORDS(i0,i1,x); 00052 jj0 = ((i0>>20)&0x7ff)-0x3ff; 00053 if(jj0<20) { 00054 if(jj0<0) { /* raise inexact if x != 0 */ 00055 if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ 00056 if(i0<0) {i0=0x80000000;i1=0;} 00057 else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} 00058 } 00059 } else { 00060 i = (0x000fffff)>>jj0; 00061 if(((i0&i)|i1)==0) return x; /* x is integral */ 00062 if(huge+x>0.0) { /* raise inexact flag */ 00063 if(i0>0) i0 += (0x00100000)>>jj0; 00064 i0 &= (~i); i1=0; 00065 } 00066 } 00067 } else if (jj0>51) { 00068 if(jj0==0x400) return x+x; /* inf or NaN */ 00069 else return x; /* x is integral */ 00070 } else { 00071 i = ((uint32_t)(0xffffffff))>>(jj0-20); 00072 if((i1&i)==0) return x; /* x is integral */ 00073 if(huge+x>0.0) { /* raise inexact flag */ 00074 if(i0>0) { 00075 if(jj0==20) i0+=1; 00076 else { 00077 j = i1 + (1<<(52-jj0)); 00078 if(j<(uint32_t)i1) i0+=1; /* got a carry */ 00079 i1 = j; 00080 } 00081 } 00082 i1 &= (~i); 00083 } 00084 } 00085 INSERT_WORDS(x,i0,i1); 00086 return x; 00087 } 00088 00089 #endif