xref: /minix3/lib/libm/noieee_src/n_floor.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1 /*      $NetBSD: n_floor.c,v 1.8 2014/03/16 09:51:39 martin Exp $ */
2 /*
3  * Copyright (c) 1985, 1993
4  *	The Regents of the University of California.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #ifndef lint
32 #if 0
33 static char sccsid[] = "@(#)floor.c	8.1 (Berkeley) 6/4/93";
34 #endif
35 #endif /* not lint */
36 
37 #define _LIBM_STATIC
38 #include "mathimpl.h"
39 
40 vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
41 
42 ic(L, 4503599627370496.0E0, 52, 1.0)			  /* 2**52 */
43 
44 #ifdef vccast
45 #define	L	vccast(L)
46 #endif
47 
48 #ifdef __weak_alias
49 __weak_alias(ceill, ceil);
50 __weak_alias(floorl, floor);
51 __weak_alias(truncl, trunc);
52 #endif
53 
54 /*
55  * floor(x) := the largest integer no larger than x;
56  * ceil(x) := -floor(-x), for all real x.
57  *
58  * Note: Inexact will be signaled if x is not an integer, as is
59  *	customary for IEEE 754.  No other signal can be emitted.
60  */
61 double
floor(double x)62 floor(double x)
63 {
64 	volatile double y;
65 
66 	if (
67 #if !defined(__vax__)&&!defined(tahoe)
68 		x != x ||	/* NaN */
69 #endif	/* !defined(__vax__)&&!defined(tahoe) */
70 		x >= L)		/* already an even integer */
71 		return x;
72 	else if (x < (double)0)
73 		return -ceil(-x);
74 	else {			/* now 0 <= x < L */
75 		y = L+x;		/* destructive store must be forced */
76 		y -= L;			/* an integer, and |x-y| < 1 */
77 		return x < y ? y-(double)1 : y;
78 	}
79 }
80 
81 float
floorf(float x)82 floorf(float x)
83 {
84 	return floor((double)x);
85 }
86 
87 double
ceil(double x)88 ceil(double x)
89 {
90 	volatile double y;
91 
92 	if (
93 #if !defined(__vax__)&&!defined(tahoe)
94 		x != x ||	/* NaN */
95 #endif	/* !defined(__vax__)&&!defined(tahoe) */
96 		x >= L)		/* already an even integer */
97 		return x;
98 	else if (x < (double)0)
99 		return -floor(-x);
100 	else {			/* now 0 <= x < L */
101 		y = L+x;		/* destructive store must be forced */
102 		y -= L;			/* an integer, and |x-y| < 1 */
103 		return x > y ? y+(double)1 : y;
104 	}
105 }
106 
107 float
ceilf(float x)108 ceilf(float x)
109 {
110 	return ceil((double)x);
111 }
112 
113 #ifndef ns32000			/* rint() is in ./NATIONAL/support.s */
114 /*
115  * algorithm for rint(x) in pseudo-pascal form ...
116  *
117  * real rint(x): real x;
118  *	... delivers integer nearest x in direction of prevailing rounding
119  *	... mode
120  * const	L = (last consecutive integer)/2
121  * 	  = 2**55; for VAX D
122  * 	  = 2**52; for IEEE 754 Double
123  * real	s,t;
124  * begin
125  * 	if x != x then return x;		... NaN
126  * 	if |x| >= L then return x;		... already an integer
127  * 	s := copysign(L,x);
128  * 	t := x + s;				... = (x+s) rounded to integer
129  * 	return t - s
130  * end;
131  *
132  * Note: Inexact will be signaled if x is not an integer, as is
133  *	customary for IEEE 754.  No other signal can be emitted.
134  */
135 double
rint(double x)136 rint(double x)
137 {
138 	double s;
139 	volatile double t;
140 	const double one = 1.0;
141 
142 #if !defined(__vax__)&&!defined(tahoe)
143 	if (x != x)				/* NaN */
144 		return (x);
145 #endif	/* !defined(__vax__)&&!defined(tahoe) */
146 	if (copysign(x,one) >= L)		/* already an integer */
147 	    return (x);
148 	s = copysign(L,x);
149 	t = x + s;				/* x+s rounded to integer */
150 	return (t - s);
151 }
152 #endif	/* not national */
153 
154 long
lrint(double x)155 lrint(double x)
156 {
157 	double s;
158 	volatile double t;
159 	const double one = 1.0;
160 
161 #if !defined(__vax__)&&!defined(tahoe)
162 	if (x != x)				/* NaN */
163 		return (x);
164 #endif	/* !defined(__vax__)&&!defined(tahoe) */
165 	if (copysign(x,one) >= L)		/* already an integer */
166 	    return (x);
167 	s = copysign(L,x);
168 	t = x + s;				/* x+s rounded to integer */
169 	return (t - s);
170 }
171 
172 long long
llrint(double x)173 llrint(double x)
174 {
175 	double s;
176 	volatile double t;
177 	const double one = 1.0;
178 
179 #if !defined(__vax__)&&!defined(tahoe)
180 	if (x != x)				/* NaN */
181 		return (x);
182 #endif	/* !defined(__vax__)&&!defined(tahoe) */
183 	if (copysign(x,one) >= L)		/* already an integer */
184 	    return (x);
185 	s = copysign(L,x);
186 	t = x + s;				/* x+s rounded to integer */
187 	return (t - s);
188 }
189 
190 long
lrintf(float x)191 lrintf(float x)
192 {
193 	float s;
194 	volatile float t;
195 	const float one = 1.0;
196 
197 #if !defined(__vax__)&&!defined(tahoe)
198 	if (x != x)				/* NaN */
199 		return (x);
200 #endif	/* !defined(__vax__)&&!defined(tahoe) */
201 	if (copysign(x,one) >= L)		/* already an integer */
202 	    return (x);
203 	s = copysign(L,x);
204 	t = x + s;				/* x+s rounded to integer */
205 	return (t - s);
206 }
207 
208 long long
llrintf(float x)209 llrintf(float x)
210 {
211 	float s;
212 	volatile float t;
213 	const float one = 1.0;
214 
215 #if !defined(__vax__)&&!defined(tahoe)
216 	if (x != x)				/* NaN */
217 		return (x);
218 #endif	/* !defined(__vax__)&&!defined(tahoe) */
219 	if (copysign(x,one) >= L)		/* already an integer */
220 	    return (x);
221 	s = copysign(L,x);
222 	t = x + s;				/* x+s rounded to integer */
223 	return (t - s);
224 }
225 
226 double
trunc(double x)227 trunc(double x)
228 {
229 	return x < 0 ? ceil(x) : floor(x);
230 }
231 
232 float
truncf(float x)233 truncf(float x)
234 {
235 	return x < 0 ? ceilf(x) : floorf(x);
236 }
237