xref: /original-bsd/lib/libm/common_source/floor.c (revision 94c97675)
1 /*
2  * Copyright (c) 1985 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  * All recipients should regard themselves as participants in an ongoing
18  * research project and hence should feel obligated to report their
19  * experiences (good or bad) with these elementary function codes, using
20  * the sendbug(8) program, to the authors.
21  */
22 
23 #ifndef lint
24 static char sccsid[] = "@(#)floor.c	5.5 (Berkeley) 09/22/88";
25 #endif /* not lint */
26 
27 #include "mathimpl.h"
28 
29 vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
30 
31 ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
32 
33 #ifdef vccast
34 #define	L	vccast(L)
35 #endif
36 
37 
38 double ceil();
39 double floor();
40 
41 /*
42  * floor(x) := the largest integer no larger than x;
43  * ceil(x) := -floor(-x), for all real x.
44  *
45  * Note: Inexact will be signaled if x is not an integer, as is
46  *	customary for IEEE 754.  No other signal can be emitted.
47  */
48 double
49 floor(x)
50 double x;
51 {
52 	double y;
53 
54 	if (
55 #if !defined(vax)&&!defined(tahoe)
56 		x != x ||	/* NaN */
57 #endif	/* !defined(vax)&&!defined(tahoe) */
58 		x >= L)		/* already an even integer */
59 		return x;
60 	else if (x < (double)0)
61 		return -ceil(-x);
62 	else {			/* now 0 <= x < L */
63 		y = L+x;		/* destructive store must be forced */
64 		y -= L;			/* an integer, and |x-y| < 1 */
65 		return x < y ? y-(double)1 : y;
66 	}
67 }
68 
69 double
70 ceil(x)
71 double x;
72 {
73 	double y;
74 
75 	if (
76 #if !defined(vax)&&!defined(tahoe)
77 		x != x ||	/* NaN */
78 #endif	/* !defined(vax)&&!defined(tahoe) */
79 		x >= L)		/* already an even integer */
80 		return x;
81 	else if (x < (double)0)
82 		return -floor(-x);
83 	else {			/* now 0 <= x < L */
84 		y = L+x;		/* destructive store must be forced */
85 		y -= L;			/* an integer, and |x-y| < 1 */
86 		return x > y ? y+(double)1 : y;
87 	}
88 }
89 
90 #ifndef national			/* rint() is in ./NATIONAL/support.s */
91 /*
92  * algorithm for rint(x) in pseudo-pascal form ...
93  *
94  * real rint(x): real x;
95  *	... delivers integer nearest x in direction of prevailing rounding
96  *	... mode
97  * const	L = (last consecutive integer)/2
98  * 	  = 2**55; for VAX D
99  * 	  = 2**52; for IEEE 754 Double
100  * real	s,t;
101  * begin
102  * 	if x != x then return x;		... NaN
103  * 	if |x| >= L then return x;		... already an integer
104  * 	s := copysign(L,x);
105  * 	t := x + s;				... = (x+s) rounded to integer
106  * 	return t - s
107  * end;
108  *
109  * Note: Inexact will be signaled if x is not an integer, as is
110  *	customary for IEEE 754.  No other signal can be emitted.
111  */
112 double
113 rint(x)
114 double x;
115 {
116 	double s,t;
117 	const double one = 1.0;
118 
119 #if !defined(vax)&&!defined(tahoe)
120 	if (x != x)				/* NaN */
121 		return (x);
122 #endif	/* !defined(vax)&&!defined(tahoe) */
123 	if (copysign(x,one) >= L)		/* already an integer */
124 	    return (x);
125 	s = copysign(L,x);
126 	t = x + s;				/* x+s rounded to integer */
127 	return (t - s);
128 }
129 #endif	/* not national */
130