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