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