xref: /csrg-svn/lib/libm/common_source/floor.c (revision 31812)
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