1 2 /* @(#)s_floor.c 5.1 93/09/24 */ 3 /* 4 * ==================================================== 5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 6 * 7 * Developed at SunPro, a Sun Microsystems, Inc. business. 8 * Permission to use, copy, modify, and distribute this 9 * software is freely granted, provided that this notice 10 * is preserved. 11 * ==================================================== 12 */ 13 14 /* 15 FUNCTION 16 <<floor>>, <<floorf>>, <<ceil>>, <<ceilf>>---floor and ceiling 17 INDEX 18 floor 19 INDEX 20 floorf 21 INDEX 22 ceil 23 INDEX 24 ceilf 25 26 ANSI_SYNOPSIS 27 #include <math.h> 28 double floor(double <[x]>); 29 float floorf(float <[x]>); 30 double ceil(double <[x]>); 31 float ceilf(float <[x]>); 32 33 TRAD_SYNOPSIS 34 #include <math.h> 35 double floor(<[x]>) 36 double <[x]>; 37 float floorf(<[x]>) 38 float <[x]>; 39 double ceil(<[x]>) 40 double <[x]>; 41 float ceilf(<[x]>) 42 float <[x]>; 43 44 DESCRIPTION 45 <<floor>> and <<floorf>> find 46 @tex 47 $\lfloor x \rfloor$, 48 @end tex 49 the nearest integer less than or equal to <[x]>. 50 <<ceil>> and <<ceilf>> find 51 @tex 52 $\lceil x\rceil$, 53 @end tex 54 the nearest integer greater than or equal to <[x]>. 55 56 RETURNS 57 <<floor>> and <<ceil>> return the integer result as a double. 58 <<floorf>> and <<ceilf>> return the integer result as a float. 59 60 PORTABILITY 61 <<floor>> and <<ceil>> are ANSI. 62 <<floorf>> and <<ceilf>> are extensions. 63 64 65 */ 66 67 /* 68 * floor(x) 69 * Return x rounded toward -inf to integral value 70 * Method: 71 * Bit twiddling. 72 * Exception: 73 * Inexact flag raised if x not equal to floor(x). 74 */ 75 76 #include "fdlibm.h" 77 78 #ifndef _DOUBLE_IS_32BITS 79 80 #ifdef __STDC__ 81 static const double huge = 1.0e300; 82 #else 83 static double huge = 1.0e300; 84 #endif 85 86 #ifdef __STDC__ floor(double x)87 double floor(double x) 88 #else 89 double floor(x) 90 double x; 91 #endif 92 { 93 __int32_t i0,i1,j0; 94 __uint32_t i,j; 95 EXTRACT_WORDS(i0,i1,x); 96 j0 = ((i0>>20)&0x7ff)-0x3ff; 97 if(j0<20) { 98 if(j0<0) { /* raise inexact if x != 0 */ 99 if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ 100 if(i0>=0) {i0=i1=0;} 101 else if(((i0&0x7fffffff)|i1)!=0) 102 { i0=0xbff00000;i1=0;} 103 } 104 } else { 105 i = (0x000fffff)>>j0; 106 if(((i0&i)|i1)==0) return x; /* x is integral */ 107 if(huge+x>0.0) { /* raise inexact flag */ 108 if(i0<0) i0 += (0x00100000)>>j0; 109 i0 &= (~i); i1=0; 110 } 111 } 112 } else if (j0>51) { 113 if(j0==0x400) return x+x; /* inf or NaN */ 114 else return x; /* x is integral */ 115 } else { 116 i = ((__uint32_t)(0xffffffff))>>(j0-20); 117 if((i1&i)==0) return x; /* x is integral */ 118 if(huge+x>0.0) { /* raise inexact flag */ 119 if(i0<0) { 120 if(j0==20) i0+=1; 121 else { 122 j = i1+(1<<(52-j0)); 123 if(j<i1) i0 +=1 ; /* got a carry */ 124 i1=j; 125 } 126 } 127 i1 &= (~i); 128 } 129 } 130 INSERT_WORDS(x,i0,i1); 131 return x; 132 } 133 134 #endif /* _DOUBLE_IS_32BITS */ 135