xref: /original-bsd/old/libm/libm/floor.c (revision d3640572)
1 /*	@(#)floor.c	4.2	09/11/85 */
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 #ifdef VAX
56 static long Lx[] = {0x5c00,0x0};		/* 2**55 */
57 #define L *(double *) Lx
58 #else	/* IEEE double */
59 static double L = 4503599627370496.0E0;		/* 2**52 */
60 #endif
61 double
62 rint(x)
63 double x;
64 {
65 	double s,t,one = 1.0,copysign();
66 #ifndef VAX
67 	if (x != x)				/* NaN */
68 		return (x);
69 #endif
70 	if (copysign(x,one) >= L)		/* already an integer */
71 	    return (x);
72 	s = copysign(L,x);
73 	t = x + s;				/* x+s rounded to integer */
74 	return (t - s);
75 }
76