xref: /original-bsd/lib/libm/common_source/floor.c (revision 2c12987e)
1 /*
2  * Copyright (c) 1985 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  * All recipients should regard themselves as participants in an ongoing
8  * research project and hence should feel obligated to report their
9  * experiences (good or bad) with these elementary function codes, using
10  * the sendbug(8) program, to the authors.
11  */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)floor.c	5.6 (Berkeley) 06/01/90";
15 #endif /* not lint */
16 
17 #include "mathimpl.h"
18 
19 vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
20 
21 ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
22 
23 #ifdef vccast
24 #define	L	vccast(L)
25 #endif
26 
27 
28 double ceil();
29 double floor();
30 
31 /*
32  * floor(x) := the largest integer no larger than x;
33  * ceil(x) := -floor(-x), for all real x.
34  *
35  * Note: Inexact will be signaled if x is not an integer, as is
36  *	customary for IEEE 754.  No other signal can be emitted.
37  */
38 double
39 floor(x)
40 double x;
41 {
42 	double y;
43 
44 	if (
45 #if !defined(vax)&&!defined(tahoe)
46 		x != x ||	/* NaN */
47 #endif	/* !defined(vax)&&!defined(tahoe) */
48 		x >= L)		/* already an even integer */
49 		return x;
50 	else if (x < (double)0)
51 		return -ceil(-x);
52 	else {			/* now 0 <= x < L */
53 		y = L+x;		/* destructive store must be forced */
54 		y -= L;			/* an integer, and |x-y| < 1 */
55 		return x < y ? y-(double)1 : y;
56 	}
57 }
58 
59 double
60 ceil(x)
61 double x;
62 {
63 	double y;
64 
65 	if (
66 #if !defined(vax)&&!defined(tahoe)
67 		x != x ||	/* NaN */
68 #endif	/* !defined(vax)&&!defined(tahoe) */
69 		x >= L)		/* already an even integer */
70 		return x;
71 	else if (x < (double)0)
72 		return -floor(-x);
73 	else {			/* now 0 <= x < L */
74 		y = L+x;		/* destructive store must be forced */
75 		y -= L;			/* an integer, and |x-y| < 1 */
76 		return x > y ? y+(double)1 : y;
77 	}
78 }
79 
80 #ifndef national			/* rint() is in ./NATIONAL/support.s */
81 /*
82  * algorithm for rint(x) in pseudo-pascal form ...
83  *
84  * real rint(x): real x;
85  *	... delivers integer nearest x in direction of prevailing rounding
86  *	... mode
87  * const	L = (last consecutive integer)/2
88  * 	  = 2**55; for VAX D
89  * 	  = 2**52; for IEEE 754 Double
90  * real	s,t;
91  * begin
92  * 	if x != x then return x;		... NaN
93  * 	if |x| >= L then return x;		... already an integer
94  * 	s := copysign(L,x);
95  * 	t := x + s;				... = (x+s) rounded to integer
96  * 	return t - s
97  * end;
98  *
99  * Note: Inexact will be signaled if x is not an integer, as is
100  *	customary for IEEE 754.  No other signal can be emitted.
101  */
102 double
103 rint(x)
104 double x;
105 {
106 	double s,t;
107 	const double one = 1.0;
108 
109 #if !defined(vax)&&!defined(tahoe)
110 	if (x != x)				/* NaN */
111 		return (x);
112 #endif	/* !defined(vax)&&!defined(tahoe) */
113 	if (copysign(x,one) >= L)		/* already an integer */
114 	    return (x);
115 	s = copysign(L,x);
116 	t = x + s;				/* x+s rounded to integer */
117 	return (t - s);
118 }
119 #endif	/* not national */
120