1*24596Szliu /* @(#)floor.c 1.1 (ELEFUNT) 09/06/85 */ 2*24596Szliu 3*24596Szliu /* 4*24596Szliu * floor and ceil-- greatest integer <= arg 5*24596Szliu * (resp least >=) 6*24596Szliu */ 7*24596Szliu 8*24596Szliu double modf(); 9*24596Szliu 10*24596Szliu double 11*24596Szliu floor(d) 12*24596Szliu double d; 13*24596Szliu { 14*24596Szliu double fract; 15*24596Szliu 16*24596Szliu if (d<0.0) { 17*24596Szliu d = -d; 18*24596Szliu fract = modf(d, &d); 19*24596Szliu if (fract != 0.0) 20*24596Szliu d += 1; 21*24596Szliu d = -d; 22*24596Szliu } else 23*24596Szliu modf(d, &d); 24*24596Szliu return(d); 25*24596Szliu } 26*24596Szliu 27*24596Szliu double 28*24596Szliu ceil(d) 29*24596Szliu double d; 30*24596Szliu { 31*24596Szliu return(-floor(-d)); 32*24596Szliu } 33*24596Szliu 34*24596Szliu /* 35*24596Szliu * algorithm for rint(x) in pseudo-pascal form ... 36*24596Szliu * 37*24596Szliu * real rint(x): real x; 38*24596Szliu * ... delivers integer nearest x in direction of prevailing rounding 39*24596Szliu * ... mode 40*24596Szliu * const L = (last consecutive integer)/2 41*24596Szliu * = 2**55; for VAX D 42*24596Szliu * = 2**52; for IEEE 754 Double 43*24596Szliu * real s,t; 44*24596Szliu * begin 45*24596Szliu * if x != x then return x; ... NaN 46*24596Szliu * if |x| >= L then return x; ... already an integer 47*24596Szliu * s := copysign(L,x); 48*24596Szliu * t := x + s; ... = (x+s) rounded to integer 49*24596Szliu * return t - s 50*24596Szliu * end; 51*24596Szliu * 52*24596Szliu * Note: Inexact will be signaled if x is not an integer, as is 53*24596Szliu * customary for IEEE 754. No other signal can be emitted. 54*24596Szliu */ 55*24596Szliu #ifdef VAX 56*24596Szliu static long Lx[] = {0x5c00,0x0}; /* 2**55 */ 57*24596Szliu #define L *(double *) Lx 58*24596Szliu #else /* IEEE double */ 59*24596Szliu static double L = 4503599627370496.0E0; /* 2**52 */ 60*24596Szliu #endif 61*24596Szliu double 62*24596Szliu rint(x) 63*24596Szliu double x; 64*24596Szliu { 65*24596Szliu double s,t,one = 1.0,copysign(); 66*24596Szliu #ifndef VAX 67*24596Szliu if (x != x) /* NaN */ 68*24596Szliu return (x); 69*24596Szliu #endif 70*24596Szliu if (copysign(x,one) >= L) /* already an integer */ 71*24596Szliu return (x); 72*24596Szliu s = copysign(L,x); 73*24596Szliu t = x + s; /* x+s rounded to integer */ 74*24596Szliu return (t - s); 75*24596Szliu } 76