1*31812Szliu /* @(#)floor.c 4.2 9/11/85; 1.4 (ucb.elefunt) 07/10/87 */ 224596Szliu 324596Szliu /* 424596Szliu * floor and ceil-- greatest integer <= arg 524596Szliu * (resp least >=) 624596Szliu */ 724596Szliu 824596Szliu double modf(); 924596Szliu 1024596Szliu double 1124596Szliu floor(d) 1224596Szliu double d; 1324596Szliu { 1424596Szliu double fract; 1524596Szliu 1624596Szliu if (d<0.0) { 1724596Szliu d = -d; 1824596Szliu fract = modf(d, &d); 1924596Szliu if (fract != 0.0) 2024596Szliu d += 1; 2124596Szliu d = -d; 2224596Szliu } else 2324596Szliu modf(d, &d); 2424596Szliu return(d); 2524596Szliu } 2624596Szliu 2724596Szliu double 2824596Szliu ceil(d) 2924596Szliu double d; 3024596Szliu { 3124596Szliu return(-floor(-d)); 3224596Szliu } 3324596Szliu 3424596Szliu /* 3524596Szliu * algorithm for rint(x) in pseudo-pascal form ... 3624596Szliu * 3724596Szliu * real rint(x): real x; 3824596Szliu * ... delivers integer nearest x in direction of prevailing rounding 3924596Szliu * ... mode 4024596Szliu * const L = (last consecutive integer)/2 4124596Szliu * = 2**55; for VAX D 4224596Szliu * = 2**52; for IEEE 754 Double 4324596Szliu * real s,t; 4424596Szliu * begin 4524596Szliu * if x != x then return x; ... NaN 4624596Szliu * if |x| >= L then return x; ... already an integer 4724596Szliu * s := copysign(L,x); 4824596Szliu * t := x + s; ... = (x+s) rounded to integer 4924596Szliu * return t - s 5024596Szliu * end; 5124596Szliu * 5224596Szliu * Note: Inexact will be signaled if x is not an integer, as is 5324596Szliu * customary for IEEE 754. No other signal can be emitted. 5424596Szliu */ 5531790Szliu #if (defined(VAX)||defined(TAHOE)) 56*31812Szliu #ifdef VAX 57*31812Szliu #define _0x(A,B) 0x/**/A/**/B 58*31812Szliu #else /* VAX */ 59*31812Szliu #define _0x(A,B) 0x/**/B/**/A 60*31812Szliu #endif /* VAX */ 61*31812Szliu static long Lx[] = {_0x(0000,5c00),_0x(0000,0000)}; /* 2**55 */ 6224596Szliu #define L *(double *) Lx 6324596Szliu #else /* IEEE double */ 6424596Szliu static double L = 4503599627370496.0E0; /* 2**52 */ 6524596Szliu #endif 6624596Szliu double 6724596Szliu rint(x) 6824596Szliu double x; 6924596Szliu { 7024596Szliu double s,t,one = 1.0,copysign(); 7131790Szliu #if (!defined(VAX)&&!defined(TAHOE)) 7224596Szliu if (x != x) /* NaN */ 7324596Szliu return (x); 7424596Szliu #endif 7524596Szliu if (copysign(x,one) >= L) /* already an integer */ 7624596Szliu return (x); 7724596Szliu s = copysign(L,x); 7824596Szliu t = x + s; /* x+s rounded to integer */ 7924596Szliu return (t - s); 8024596Szliu } 81