t_next.c revision 1.7.6.3 1 1.7.6.3 martin /* $NetBSD: t_next.c,v 1.7.6.3 2024/10/15 13:27:10 martin Exp $ */
2 1.7.6.2 martin
3 1.7.6.2 martin /*-
4 1.7.6.2 martin * Copyright (c) 2024 The NetBSD Foundation, Inc.
5 1.7.6.2 martin * All rights reserved.
6 1.7.6.2 martin *
7 1.7.6.2 martin * Redistribution and use in source and binary forms, with or without
8 1.7.6.2 martin * modification, are permitted provided that the following conditions
9 1.7.6.2 martin * are met:
10 1.7.6.2 martin * 1. Redistributions of source code must retain the above copyright
11 1.7.6.2 martin * notice, this list of conditions and the following disclaimer.
12 1.7.6.2 martin * 2. Redistributions in binary form must reproduce the above copyright
13 1.7.6.2 martin * notice, this list of conditions and the following disclaimer in the
14 1.7.6.2 martin * documentation and/or other materials provided with the distribution.
15 1.7.6.2 martin *
16 1.7.6.2 martin * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.7.6.2 martin * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.7.6.2 martin * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.7.6.2 martin * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.7.6.2 martin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.7.6.2 martin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.7.6.2 martin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.7.6.2 martin * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.7.6.2 martin * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.7.6.2 martin * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.7.6.2 martin * POSSIBILITY OF SUCH DAMAGE.
27 1.7.6.2 martin */
28 1.7.6.2 martin
29 1.7.6.2 martin #include <sys/cdefs.h>
30 1.7.6.3 martin __RCSID("$NetBSD: t_next.c,v 1.7.6.3 2024/10/15 13:27:10 martin Exp $");
31 1.7.6.2 martin
32 1.7.6.2 martin #include <atf-c.h>
33 1.7.6.2 martin #include <float.h>
34 1.7.6.2 martin #include <math.h>
35 1.7.6.2 martin
36 1.7.6.2 martin #ifdef __vax__ /* XXX PR 57881: vax libm is missing various symbols */
37 1.7.6.2 martin
38 1.7.6.2 martin ATF_TC(vaxafter);
39 1.7.6.2 martin ATF_TC_HEAD(vaxafter, tc)
40 1.7.6.2 martin {
41 1.7.6.2 martin
42 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "vax nextafter/nexttoward reminder");
43 1.7.6.2 martin }
44 1.7.6.2 martin ATF_TC_BODY(vaxafter, tc)
45 1.7.6.2 martin {
46 1.7.6.2 martin
47 1.7.6.2 martin atf_tc_expect_fail("PR 57881: vax libm is missing various symbols");
48 1.7.6.2 martin atf_tc_fail("missing nextafter{,f,l} and nexttoward{,f,l} on vax");
49 1.7.6.2 martin }
50 1.7.6.2 martin
51 1.7.6.2 martin #else /* !__vax__ */
52 1.7.6.2 martin
53 1.7.6.2 martin #define CHECK(i, next, x, d, y) do \
54 1.7.6.2 martin { \
55 1.7.6.2 martin volatile __typeof__(x) check_x = (x); \
56 1.7.6.2 martin volatile __typeof__(d) check_d = (d); \
57 1.7.6.2 martin volatile __typeof__(y) check_y = (y); \
58 1.7.6.2 martin const volatile __typeof__(y) check_tmp = (next)(check_x, check_d); \
59 1.7.6.2 martin ATF_CHECK_MSG(check_tmp == check_y, \
60 1.7.6.2 martin "[%u] %s(%s=%La=%Lg, %s=%La=%Lg)=%La=%Lg != %s=%La=%Lg", \
61 1.7.6.2 martin (i), #next, \
62 1.7.6.2 martin #x, (long double)check_x, (long double)check_x, \
63 1.7.6.2 martin #d, (long double)check_d, (long double)check_d, \
64 1.7.6.2 martin (long double)check_tmp, (long double)check_tmp, \
65 1.7.6.2 martin #y, (long double)check_y, (long double)check_y); \
66 1.7.6.2 martin } while (0)
67 1.7.6.2 martin
68 1.7.6.2 martin /*
69 1.7.6.2 martin * check(x, n)
70 1.7.6.2 martin *
71 1.7.6.2 martin * x[0], x[1], ..., x[n - 1] are consecutive double floating-point
72 1.7.6.2 martin * numbers. Verify nextafter and nexttoward follow exactly this
73 1.7.6.2 martin * sequence, forward and back, and in negative.
74 1.7.6.2 martin */
75 1.7.6.2 martin static void
76 1.7.6.2 martin check(const double *x, unsigned n)
77 1.7.6.2 martin {
78 1.7.6.2 martin unsigned i;
79 1.7.6.2 martin
80 1.7.6.2 martin for (i = 0; i < n; i++) {
81 1.7.6.2 martin CHECK(i, nextafter, x[i], x[i], x[i]);
82 1.7.6.2 martin CHECK(i, nexttoward, x[i], x[i], x[i]);
83 1.7.6.2 martin CHECK(i, nextafter, -x[i], -x[i], -x[i]);
84 1.7.6.2 martin CHECK(i, nexttoward, -x[i], -x[i], -x[i]);
85 1.7.6.2 martin }
86 1.7.6.2 martin
87 1.7.6.2 martin for (i = 0; i < n - 1; i++) {
88 1.7.6.2 martin ATF_REQUIRE_MSG(x[i] < x[i + 1], "i=%u", i);
89 1.7.6.2 martin
90 1.7.6.2 martin if (isnormal(x[i])) {
91 1.7.6.2 martin CHECK(i, nexttoward, x[i], x[i]*(1 + LDBL_EPSILON),
92 1.7.6.2 martin x[i + 1]);
93 1.7.6.2 martin }
94 1.7.6.2 martin
95 1.7.6.2 martin CHECK(i, nextafter, x[i], x[i + 1], x[i + 1]);
96 1.7.6.2 martin CHECK(i, nexttoward, x[i], x[i + 1], x[i + 1]);
97 1.7.6.2 martin CHECK(i, nextafter, x[i], x[n - 1], x[i + 1]);
98 1.7.6.2 martin CHECK(i, nexttoward, x[i], x[n - 1], x[i + 1]);
99 1.7.6.2 martin CHECK(i, nextafter, x[i], INFINITY, x[i + 1]);
100 1.7.6.2 martin CHECK(i, nexttoward, x[i], INFINITY, x[i + 1]);
101 1.7.6.2 martin
102 1.7.6.2 martin CHECK(i, nextafter, -x[i], -x[i + 1], -x[i + 1]);
103 1.7.6.2 martin CHECK(i, nexttoward, -x[i], -x[i + 1], -x[i + 1]);
104 1.7.6.2 martin CHECK(i, nextafter, -x[i], -x[n - 1], -x[i + 1]);
105 1.7.6.2 martin CHECK(i, nexttoward, -x[i], -x[n - 1], -x[i + 1]);
106 1.7.6.2 martin CHECK(i, nextafter, -x[i], -INFINITY, -x[i + 1]);
107 1.7.6.2 martin CHECK(i, nexttoward, -x[i], -INFINITY, -x[i + 1]);
108 1.7.6.2 martin }
109 1.7.6.2 martin
110 1.7.6.2 martin for (i = n; i --> 1;) {
111 1.7.6.2 martin ATF_REQUIRE_MSG(x[i - 1] < x[i], "i=%u", i);
112 1.7.6.2 martin
113 1.7.6.3 martin #ifdef __HAVE_LONG_DOUBLE
114 1.7.6.2 martin if (isnormal(x[i])) {
115 1.7.6.2 martin CHECK(i, nexttoward, x[i], x[i]*(1 - LDBL_EPSILON/2),
116 1.7.6.2 martin x[i - 1]);
117 1.7.6.2 martin }
118 1.7.6.3 martin #endif
119 1.7.6.2 martin
120 1.7.6.2 martin CHECK(i, nextafter, x[i], x[i - 1], x[i - 1]);
121 1.7.6.2 martin CHECK(i, nexttoward, x[i], x[i - 1], x[i - 1]);
122 1.7.6.2 martin CHECK(i, nextafter, x[i], x[0], x[i - 1]);
123 1.7.6.2 martin CHECK(i, nexttoward, x[i], x[0], x[i - 1]);
124 1.7.6.2 martin CHECK(i, nextafter, x[i], +0., x[i - 1]);
125 1.7.6.2 martin CHECK(i, nexttoward, x[i], +0., x[i - 1]);
126 1.7.6.2 martin CHECK(i, nextafter, x[i], -0., x[i - 1]);
127 1.7.6.2 martin CHECK(i, nexttoward, x[i], -0., x[i - 1]);
128 1.7.6.2 martin CHECK(i, nextafter, x[i], -x[0], x[i - 1]);
129 1.7.6.2 martin CHECK(i, nexttoward, x[i], -x[0], x[i - 1]);
130 1.7.6.2 martin CHECK(i, nextafter, x[i], -x[i], x[i - 1]);
131 1.7.6.2 martin CHECK(i, nexttoward, x[i], -x[i], x[i - 1]);
132 1.7.6.2 martin CHECK(i, nextafter, x[i], -INFINITY, x[i - 1]);
133 1.7.6.2 martin CHECK(i, nexttoward, x[i], -INFINITY, x[i - 1]);
134 1.7.6.2 martin
135 1.7.6.2 martin CHECK(i, nextafter, -x[i], -x[i - 1], -x[i - 1]);
136 1.7.6.2 martin CHECK(i, nexttoward, -x[i], -x[i - 1], -x[i - 1]);
137 1.7.6.2 martin CHECK(i, nextafter, -x[i], -x[0], -x[i - 1]);
138 1.7.6.2 martin CHECK(i, nexttoward, -x[i], -x[0], -x[i - 1]);
139 1.7.6.2 martin CHECK(i, nextafter, -x[i], -0., -x[i - 1]);
140 1.7.6.2 martin CHECK(i, nexttoward, -x[i], -0., -x[i - 1]);
141 1.7.6.2 martin CHECK(i, nextafter, -x[i], +0., -x[i - 1]);
142 1.7.6.2 martin CHECK(i, nexttoward, -x[i], +0., -x[i - 1]);
143 1.7.6.2 martin CHECK(i, nextafter, -x[i], x[0], -x[i - 1]);
144 1.7.6.2 martin CHECK(i, nexttoward, -x[i], x[0], -x[i - 1]);
145 1.7.6.2 martin CHECK(i, nextafter, -x[i], INFINITY, -x[i - 1]);
146 1.7.6.2 martin CHECK(i, nexttoward, -x[i], INFINITY, -x[i - 1]);
147 1.7.6.2 martin }
148 1.7.6.2 martin }
149 1.7.6.2 martin
150 1.7.6.2 martin /*
151 1.7.6.2 martin * checkf(x, n)
152 1.7.6.2 martin *
153 1.7.6.2 martin * x[0], x[1], ..., x[n - 1] are consecutive single floating-point
154 1.7.6.2 martin * numbers. Verify nextafterf and nexttowardf follow exactly this
155 1.7.6.2 martin * sequence, forward and back, and in negative.
156 1.7.6.2 martin */
157 1.7.6.2 martin static void
158 1.7.6.2 martin checkf(const float *x, unsigned n)
159 1.7.6.2 martin {
160 1.7.6.2 martin unsigned i;
161 1.7.6.2 martin
162 1.7.6.2 martin for (i = 0; i < n; i++) {
163 1.7.6.2 martin CHECK(i, nextafterf, x[i], x[i], x[i]);
164 1.7.6.2 martin CHECK(i, nexttowardf, x[i], x[i], x[i]);
165 1.7.6.2 martin CHECK(i, nextafterf, -x[i], -x[i], -x[i]);
166 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], -x[i], -x[i]);
167 1.7.6.2 martin }
168 1.7.6.2 martin
169 1.7.6.2 martin for (i = 0; i < n - 1; i++) {
170 1.7.6.2 martin ATF_REQUIRE_MSG(x[i] < x[i + 1], "i=%u", i);
171 1.7.6.2 martin
172 1.7.6.2 martin if (isnormal(x[i])) {
173 1.7.6.2 martin CHECK(i, nexttowardf, x[i], x[i]*(1 + LDBL_EPSILON),
174 1.7.6.2 martin x[i + 1]);
175 1.7.6.2 martin }
176 1.7.6.2 martin
177 1.7.6.2 martin CHECK(i, nextafterf, x[i], x[i + 1], x[i + 1]);
178 1.7.6.2 martin CHECK(i, nexttowardf, x[i], x[i + 1], x[i + 1]);
179 1.7.6.2 martin CHECK(i, nextafterf, x[i], x[n - 1], x[i + 1]);
180 1.7.6.2 martin CHECK(i, nexttowardf, x[i], x[n - 1], x[i + 1]);
181 1.7.6.2 martin CHECK(i, nextafterf, x[i], INFINITY, x[i + 1]);
182 1.7.6.2 martin CHECK(i, nexttowardf, x[i], INFINITY, x[i + 1]);
183 1.7.6.2 martin
184 1.7.6.2 martin CHECK(i, nextafterf, -x[i], -x[i + 1], -x[i + 1]);
185 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], -x[i + 1], -x[i + 1]);
186 1.7.6.2 martin CHECK(i, nextafterf, -x[i], -x[n - 1], -x[i + 1]);
187 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], -x[n - 1], -x[i + 1]);
188 1.7.6.2 martin CHECK(i, nextafterf, -x[i], -INFINITY, -x[i + 1]);
189 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], -INFINITY, -x[i + 1]);
190 1.7.6.2 martin }
191 1.7.6.2 martin
192 1.7.6.2 martin for (i = n; i --> 1;) {
193 1.7.6.2 martin ATF_REQUIRE_MSG(x[i - 1] < x[i], "i=%u", i);
194 1.7.6.2 martin
195 1.7.6.2 martin if (isnormal(x[i])) {
196 1.7.6.2 martin CHECK(i, nexttowardf, x[i], x[i]*(1 - LDBL_EPSILON/2),
197 1.7.6.2 martin x[i - 1]);
198 1.7.6.2 martin }
199 1.7.6.2 martin
200 1.7.6.2 martin CHECK(i, nextafterf, x[i], x[i - 1], x[i - 1]);
201 1.7.6.2 martin CHECK(i, nexttowardf, x[i], x[i - 1], x[i - 1]);
202 1.7.6.2 martin CHECK(i, nextafterf, x[i], x[0], x[i - 1]);
203 1.7.6.2 martin CHECK(i, nexttowardf, x[i], x[0], x[i - 1]);
204 1.7.6.2 martin CHECK(i, nextafterf, x[i], +0., x[i - 1]);
205 1.7.6.2 martin CHECK(i, nexttowardf, x[i], +0., x[i - 1]);
206 1.7.6.2 martin CHECK(i, nextafterf, x[i], -0., x[i - 1]);
207 1.7.6.2 martin CHECK(i, nexttowardf, x[i], -0., x[i - 1]);
208 1.7.6.2 martin CHECK(i, nextafterf, x[i], -x[0], x[i - 1]);
209 1.7.6.2 martin CHECK(i, nexttowardf, x[i], -x[0], x[i - 1]);
210 1.7.6.2 martin CHECK(i, nextafterf, x[i], -x[i], x[i - 1]);
211 1.7.6.2 martin CHECK(i, nexttowardf, x[i], -x[i], x[i - 1]);
212 1.7.6.2 martin CHECK(i, nextafterf, x[i], -INFINITY, x[i - 1]);
213 1.7.6.2 martin CHECK(i, nexttowardf, x[i], -INFINITY, x[i - 1]);
214 1.7.6.2 martin
215 1.7.6.2 martin CHECK(i, nextafterf, -x[i], -x[i - 1], -x[i - 1]);
216 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], -x[i - 1], -x[i - 1]);
217 1.7.6.2 martin CHECK(i, nextafterf, -x[i], -x[0], -x[i - 1]);
218 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], -x[0], -x[i - 1]);
219 1.7.6.2 martin CHECK(i, nextafterf, -x[i], -0., -x[i - 1]);
220 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], -0., -x[i - 1]);
221 1.7.6.2 martin CHECK(i, nextafterf, -x[i], +0., -x[i - 1]);
222 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], +0., -x[i - 1]);
223 1.7.6.2 martin CHECK(i, nextafterf, -x[i], x[0], -x[i - 1]);
224 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], x[0], -x[i - 1]);
225 1.7.6.2 martin CHECK(i, nextafterf, -x[i], INFINITY, -x[i - 1]);
226 1.7.6.2 martin CHECK(i, nexttowardf, -x[i], INFINITY, -x[i - 1]);
227 1.7.6.2 martin }
228 1.7.6.2 martin }
229 1.7.6.2 martin
230 1.7.6.2 martin /*
231 1.7.6.2 martin * checkl(x, n)
232 1.7.6.2 martin *
233 1.7.6.2 martin * x[0], x[1], ..., x[n - 1] are consecutive long double
234 1.7.6.2 martin * floating-point numbers. Verify nextafterl and nexttowardl
235 1.7.6.2 martin * follow exactly this sequence, forward and back, and in
236 1.7.6.2 martin * negative.
237 1.7.6.2 martin */
238 1.7.6.2 martin static void
239 1.7.6.2 martin checkl(const long double *x, unsigned n)
240 1.7.6.2 martin {
241 1.7.6.2 martin unsigned i;
242 1.7.6.2 martin
243 1.7.6.2 martin for (i = 0; i < n; i++) {
244 1.7.6.2 martin CHECK(i, nextafterl, x[i], x[i], x[i]);
245 1.7.6.2 martin CHECK(i, nexttowardl, x[i], x[i], x[i]);
246 1.7.6.2 martin CHECK(i, nextafterl, -x[i], -x[i], -x[i]);
247 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], -x[i], -x[i]);
248 1.7.6.2 martin }
249 1.7.6.2 martin
250 1.7.6.2 martin for (i = 0; i < n - 1; i++) {
251 1.7.6.2 martin ATF_REQUIRE_MSG(x[i] < x[i + 1], "i=%u", i);
252 1.7.6.2 martin
253 1.7.6.2 martin CHECK(i, nextafterl, x[i], x[i + 1], x[i + 1]);
254 1.7.6.2 martin CHECK(i, nexttowardl, x[i], x[i + 1], x[i + 1]);
255 1.7.6.2 martin CHECK(i, nextafterl, x[i], x[n - 1], x[i + 1]);
256 1.7.6.2 martin CHECK(i, nexttowardl, x[i], x[n - 1], x[i + 1]);
257 1.7.6.2 martin CHECK(i, nextafterl, x[i], INFINITY, x[i + 1]);
258 1.7.6.2 martin CHECK(i, nexttowardl, x[i], INFINITY, x[i + 1]);
259 1.7.6.2 martin
260 1.7.6.2 martin CHECK(i, nextafterl, -x[i], -x[i + 1], -x[i + 1]);
261 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], -x[i + 1], -x[i + 1]);
262 1.7.6.2 martin CHECK(i, nextafterl, -x[i], -x[n - 1], -x[i + 1]);
263 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], -x[n - 1], -x[i + 1]);
264 1.7.6.2 martin CHECK(i, nextafterl, -x[i], -INFINITY, -x[i + 1]);
265 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], -INFINITY, -x[i + 1]);
266 1.7.6.2 martin }
267 1.7.6.2 martin
268 1.7.6.2 martin for (i = n; i --> 1;) {
269 1.7.6.2 martin ATF_REQUIRE_MSG(x[i - 1] < x[i], "i=%u", i);
270 1.7.6.2 martin
271 1.7.6.2 martin CHECK(i, nextafterl, x[i], x[i - 1], x[i - 1]);
272 1.7.6.2 martin CHECK(i, nexttowardl, x[i], x[i - 1], x[i - 1]);
273 1.7.6.2 martin CHECK(i, nextafterl, x[i], x[0], x[i - 1]);
274 1.7.6.2 martin CHECK(i, nexttowardl, x[i], x[0], x[i - 1]);
275 1.7.6.2 martin CHECK(i, nextafterl, x[i], +0., x[i - 1]);
276 1.7.6.2 martin CHECK(i, nexttowardl, x[i], +0., x[i - 1]);
277 1.7.6.2 martin CHECK(i, nextafterl, x[i], -0., x[i - 1]);
278 1.7.6.2 martin CHECK(i, nexttowardl, x[i], -0., x[i - 1]);
279 1.7.6.2 martin CHECK(i, nextafterl, x[i], -x[0], x[i - 1]);
280 1.7.6.2 martin CHECK(i, nexttowardl, x[i], -x[0], x[i - 1]);
281 1.7.6.2 martin CHECK(i, nextafterl, x[i], -x[i], x[i - 1]);
282 1.7.6.2 martin CHECK(i, nexttowardl, x[i], -x[i], x[i - 1]);
283 1.7.6.2 martin CHECK(i, nextafterl, x[i], -INFINITY, x[i - 1]);
284 1.7.6.2 martin CHECK(i, nexttowardl, x[i], -INFINITY, x[i - 1]);
285 1.7.6.2 martin
286 1.7.6.2 martin CHECK(i, nextafterl, -x[i], -x[i - 1], -x[i - 1]);
287 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], -x[i - 1], -x[i - 1]);
288 1.7.6.2 martin CHECK(i, nextafterl, -x[i], -x[0], -x[i - 1]);
289 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], -x[0], -x[i - 1]);
290 1.7.6.2 martin CHECK(i, nextafterl, -x[i], -0., -x[i - 1]);
291 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], -0., -x[i - 1]);
292 1.7.6.2 martin CHECK(i, nextafterl, -x[i], +0., -x[i - 1]);
293 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], +0., -x[i - 1]);
294 1.7.6.2 martin CHECK(i, nextafterl, -x[i], x[0], -x[i - 1]);
295 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], x[0], -x[i - 1]);
296 1.7.6.2 martin CHECK(i, nextafterl, -x[i], INFINITY, -x[i - 1]);
297 1.7.6.2 martin CHECK(i, nexttowardl, -x[i], INFINITY, -x[i - 1]);
298 1.7.6.2 martin }
299 1.7.6.2 martin }
300 1.7.6.2 martin
301 1.7.6.2 martin ATF_TC(next_nan);
302 1.7.6.2 martin ATF_TC_HEAD(next_nan, tc)
303 1.7.6.2 martin {
304 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward on NaN");
305 1.7.6.2 martin }
306 1.7.6.2 martin ATF_TC_BODY(next_nan, tc)
307 1.7.6.2 martin {
308 1.7.6.2 martin #ifdef NAN
309 1.7.6.2 martin /* XXX verify the NaN is quiet */
310 1.7.6.2 martin ATF_CHECK(isnan(nextafter(NAN, 0)));
311 1.7.6.2 martin ATF_CHECK(isnan(nexttoward(NAN, 0)));
312 1.7.6.2 martin ATF_CHECK(isnan(nextafter(0, NAN)));
313 1.7.6.2 martin ATF_CHECK(isnan(nexttoward(0, NAN)));
314 1.7.6.2 martin #else
315 1.7.6.2 martin atf_tc_skip("no NaNs on this architecture");
316 1.7.6.2 martin #endif
317 1.7.6.2 martin }
318 1.7.6.2 martin
319 1.7.6.2 martin ATF_TC(next_signed_0);
320 1.7.6.2 martin ATF_TC_HEAD(next_signed_0, tc)
321 1.7.6.2 martin {
322 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward on signed 0");
323 1.7.6.2 martin }
324 1.7.6.2 martin ATF_TC_BODY(next_signed_0, tc)
325 1.7.6.2 martin {
326 1.7.6.2 martin volatile double z_pos = +0.;
327 1.7.6.2 martin volatile double z_neg = -0.;
328 1.7.6.2 martin #ifdef __DBL_HAS_DENORM__
329 1.7.6.2 martin volatile double m = __DBL_DENORM_MIN__;
330 1.7.6.2 martin #else
331 1.7.6.2 martin volatile double m = DBL_MIN;
332 1.7.6.2 martin #endif
333 1.7.6.2 martin
334 1.7.6.2 martin if (signbit(z_pos) == signbit(z_neg))
335 1.7.6.2 martin atf_tc_skip("no signed zeroes on this architecture");
336 1.7.6.2 martin
337 1.7.6.2 martin /*
338 1.7.6.2 martin * `nextUp(x) is the least floating-point number in the format
339 1.7.6.2 martin * of x that compares greater than x. [...] nextDown(x) is
340 1.7.6.2 martin * -nextUp(-x).'
341 1.7.6.2 martin * --IEEE 754-2019, 5.3.1 General operations, p. 19
342 1.7.6.2 martin *
343 1.7.6.2 martin * Verify that nextafter and nexttoward, which implement the
344 1.7.6.2 martin * nextUp and nextDown operations, obey this rule and don't
345 1.7.6.2 martin * send -0 to +0 or +0 to -0, respectively.
346 1.7.6.2 martin */
347 1.7.6.2 martin
348 1.7.6.2 martin CHECK(0, nextafter, z_neg, +INFINITY, m);
349 1.7.6.2 martin CHECK(1, nexttoward, z_neg, +INFINITY, m);
350 1.7.6.2 martin CHECK(2, nextafter, z_pos, +INFINITY, m);
351 1.7.6.2 martin CHECK(3, nexttoward, z_pos, +INFINITY, m);
352 1.7.6.2 martin
353 1.7.6.2 martin CHECK(4, nextafter, z_pos, -INFINITY, -m);
354 1.7.6.2 martin CHECK(5, nexttoward, z_pos, -INFINITY, -m);
355 1.7.6.2 martin CHECK(6, nextafter, z_neg, -INFINITY, -m);
356 1.7.6.2 martin CHECK(7, nexttoward, z_neg, -INFINITY, -m);
357 1.7.6.2 martin
358 1.7.6.2 martin /*
359 1.7.6.2 martin * `If x is the negative number of least magnitude in x's
360 1.7.6.2 martin * format, nextUp(x) is -0.'
361 1.7.6.2 martin * --IEEE 754-2019, 5.3.1 General operations, p. 19
362 1.7.6.2 martin *
363 1.7.6.2 martin * Verify that nextafter and nexttoward return the correctly
364 1.7.6.2 martin * signed zero.
365 1.7.6.2 martin */
366 1.7.6.2 martin CHECK(8, nextafter, -m, +INFINITY, 0);
367 1.7.6.2 martin CHECK(9, nexttoward, -m, +INFINITY, 0);
368 1.7.6.2 martin ATF_CHECK(signbit(nextafter(-m, +INFINITY)) != 0);
369 1.7.6.2 martin CHECK(10, nextafter, m, -INFINITY, 0);
370 1.7.6.2 martin CHECK(11, nexttoward, m, -INFINITY, 0);
371 1.7.6.2 martin ATF_CHECK(signbit(nextafter(m, -INFINITY)) == 0);
372 1.7.6.2 martin }
373 1.7.6.2 martin
374 1.7.6.2 martin ATF_TC(next_near_0);
375 1.7.6.2 martin ATF_TC_HEAD(next_near_0, tc)
376 1.7.6.2 martin {
377 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 0");
378 1.7.6.2 martin }
379 1.7.6.2 martin ATF_TC_BODY(next_near_0, tc)
380 1.7.6.2 martin {
381 1.7.6.2 martin static const double x[] = {
382 1.7.6.2 martin [0] = 0,
383 1.7.6.2 martin #ifdef __DBL_HAS_DENORM__
384 1.7.6.2 martin [1] = __DBL_DENORM_MIN__,
385 1.7.6.2 martin [2] = 2*__DBL_DENORM_MIN__,
386 1.7.6.2 martin [3] = 3*__DBL_DENORM_MIN__,
387 1.7.6.2 martin [4] = 4*__DBL_DENORM_MIN__,
388 1.7.6.2 martin #else
389 1.7.6.2 martin [1] = DBL_MIN,
390 1.7.6.2 martin [2] = DBL_MIN*(1 + DBL_EPSILON),
391 1.7.6.2 martin [3] = DBL_MIN*(1 + 2*DBL_EPSILON),
392 1.7.6.2 martin [4] = DBL_MIN*(1 + 3*DBL_EPSILON),
393 1.7.6.2 martin #endif
394 1.7.6.2 martin };
395 1.7.6.2 martin
396 1.7.6.2 martin check(x, __arraycount(x));
397 1.7.6.2 martin }
398 1.7.6.2 martin
399 1.7.6.2 martin ATF_TC(next_near_sub_normal);
400 1.7.6.2 martin ATF_TC_HEAD(next_near_sub_normal, tc)
401 1.7.6.2 martin {
402 1.7.6.2 martin atf_tc_set_md_var(tc, "descr",
403 1.7.6.2 martin "nextafter/nexttoward near the subnormal/normal boundary");
404 1.7.6.2 martin }
405 1.7.6.2 martin ATF_TC_BODY(next_near_sub_normal, tc)
406 1.7.6.2 martin {
407 1.7.6.2 martin #ifdef __DBL_HAS_DENORM__
408 1.7.6.2 martin static const double x[] = {
409 1.7.6.2 martin [0] = DBL_MIN - 3*__DBL_DENORM_MIN__,
410 1.7.6.2 martin [1] = DBL_MIN - 2*__DBL_DENORM_MIN__,
411 1.7.6.2 martin [2] = DBL_MIN - __DBL_DENORM_MIN__,
412 1.7.6.2 martin [3] = DBL_MIN,
413 1.7.6.2 martin [4] = DBL_MIN + __DBL_DENORM_MIN__,
414 1.7.6.2 martin [5] = DBL_MIN + 2*__DBL_DENORM_MIN__,
415 1.7.6.2 martin [6] = DBL_MIN + 3*__DBL_DENORM_MIN__,
416 1.7.6.2 martin };
417 1.7.6.2 martin
418 1.7.6.2 martin check(x, __arraycount(x));
419 1.7.6.2 martin #else /* !__DBL_HAS_DENORM__ */
420 1.7.6.2 martin atf_tc_skip("no subnormals on this architecture");
421 1.7.6.2 martin #endif /* !__DBL_HAS_DENORM__ */
422 1.7.6.2 martin }
423 1.7.6.2 martin
424 1.7.6.2 martin ATF_TC(next_near_1);
425 1.7.6.2 martin ATF_TC_HEAD(next_near_1, tc)
426 1.7.6.2 martin {
427 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 1");
428 1.7.6.2 martin }
429 1.7.6.2 martin ATF_TC_BODY(next_near_1, tc)
430 1.7.6.2 martin {
431 1.7.6.2 martin static const double x[] = {
432 1.7.6.2 martin [0] = 1 - 3*DBL_EPSILON/2,
433 1.7.6.2 martin [1] = 1 - 2*DBL_EPSILON/2,
434 1.7.6.2 martin [2] = 1 - DBL_EPSILON/2,
435 1.7.6.2 martin [3] = 1,
436 1.7.6.2 martin [4] = 1 + DBL_EPSILON,
437 1.7.6.2 martin [5] = 1 + 2*DBL_EPSILON,
438 1.7.6.2 martin [6] = 1 + 3*DBL_EPSILON,
439 1.7.6.2 martin };
440 1.7.6.2 martin
441 1.7.6.2 martin check(x, __arraycount(x));
442 1.7.6.2 martin }
443 1.7.6.2 martin
444 1.7.6.2 martin ATF_TC(next_near_1_5);
445 1.7.6.2 martin ATF_TC_HEAD(next_near_1_5, tc)
446 1.7.6.2 martin {
447 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 1.5");
448 1.7.6.2 martin }
449 1.7.6.2 martin ATF_TC_BODY(next_near_1_5, tc)
450 1.7.6.2 martin {
451 1.7.6.2 martin static const double x[] = {
452 1.7.6.2 martin [0] = 1.5 - 3*DBL_EPSILON,
453 1.7.6.2 martin [1] = 1.5 - 2*DBL_EPSILON,
454 1.7.6.2 martin [2] = 1.5 - DBL_EPSILON,
455 1.7.6.2 martin [3] = 1.5,
456 1.7.6.2 martin [4] = 1.5 + DBL_EPSILON,
457 1.7.6.2 martin [5] = 1.5 + 2*DBL_EPSILON,
458 1.7.6.2 martin [6] = 1.5 + 3*DBL_EPSILON,
459 1.7.6.2 martin };
460 1.7.6.2 martin
461 1.7.6.2 martin check(x, __arraycount(x));
462 1.7.6.2 martin }
463 1.7.6.2 martin
464 1.7.6.2 martin ATF_TC(next_near_infinity);
465 1.7.6.2 martin ATF_TC_HEAD(next_near_infinity, tc)
466 1.7.6.2 martin {
467 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near infinity");
468 1.7.6.2 martin }
469 1.7.6.2 martin ATF_TC_BODY(next_near_infinity, tc)
470 1.7.6.2 martin {
471 1.7.6.2 martin static const double x[] = {
472 1.7.6.2 martin [0] = DBL_MAX,
473 1.7.6.2 martin [1] = INFINITY,
474 1.7.6.2 martin };
475 1.7.6.2 martin volatile double t;
476 1.7.6.2 martin
477 1.7.6.2 martin if (!isinf(INFINITY))
478 1.7.6.2 martin atf_tc_skip("no infinities on this architecture");
479 1.7.6.2 martin
480 1.7.6.2 martin check(x, __arraycount(x));
481 1.7.6.2 martin
482 1.7.6.2 martin ATF_CHECK_EQ_MSG((t = nextafter(INFINITY, INFINITY)), INFINITY,
483 1.7.6.2 martin "t=%a=%g", t, t);
484 1.7.6.2 martin ATF_CHECK_EQ_MSG((t = nextafter(-INFINITY, -INFINITY)), -INFINITY,
485 1.7.6.2 martin "t=%a=%g", t, t);
486 1.7.6.2 martin }
487 1.7.6.2 martin
488 1.7.6.2 martin ATF_TC(nextf_nan);
489 1.7.6.2 martin ATF_TC_HEAD(nextf_nan, tc)
490 1.7.6.2 martin {
491 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf on NaN");
492 1.7.6.2 martin }
493 1.7.6.2 martin ATF_TC_BODY(nextf_nan, tc)
494 1.7.6.2 martin {
495 1.7.6.2 martin #ifdef NAN
496 1.7.6.2 martin /* XXX verify the NaN is quiet */
497 1.7.6.2 martin ATF_CHECK(isnan(nextafterf(NAN, 0)));
498 1.7.6.2 martin ATF_CHECK(isnan(nexttowardf(NAN, 0)));
499 1.7.6.2 martin ATF_CHECK(isnan(nextafterf(0, NAN)));
500 1.7.6.2 martin ATF_CHECK(isnan(nexttowardf(0, NAN)));
501 1.7.6.2 martin #else
502 1.7.6.2 martin atf_tc_skip("no NaNs on this architecture");
503 1.7.6.2 martin #endif
504 1.7.6.2 martin }
505 1.7.6.2 martin
506 1.7.6.2 martin ATF_TC(nextf_signed_0);
507 1.7.6.2 martin ATF_TC_HEAD(nextf_signed_0, tc)
508 1.7.6.2 martin {
509 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf on signed 0");
510 1.7.6.2 martin }
511 1.7.6.2 martin ATF_TC_BODY(nextf_signed_0, tc)
512 1.7.6.2 martin {
513 1.7.6.2 martin volatile float z_pos = +0.;
514 1.7.6.2 martin volatile float z_neg = -0.;
515 1.7.6.2 martin #ifdef __FLT_HAS_DENORM__
516 1.7.6.2 martin volatile float m = __FLT_DENORM_MIN__;
517 1.7.6.2 martin #else
518 1.7.6.2 martin volatile float m = FLT_MIN;
519 1.7.6.2 martin #endif
520 1.7.6.2 martin
521 1.7.6.2 martin if (signbit(z_pos) == signbit(z_neg))
522 1.7.6.2 martin atf_tc_skip("no signed zeroes on this architecture");
523 1.7.6.2 martin
524 1.7.6.2 martin /*
525 1.7.6.2 martin * `nextUp(x) is the least floating-point number in the format
526 1.7.6.2 martin * of x that compares greater than x. [...] nextDown(x) is
527 1.7.6.2 martin * -nextUp(-x).'
528 1.7.6.2 martin * --IEEE 754-2019, 5.3.1 General operations, p. 19
529 1.7.6.2 martin *
530 1.7.6.2 martin * Verify that nextafterf and nexttowardf, which implement the
531 1.7.6.2 martin * nextUp and nextDown operations, obey this rule and don't
532 1.7.6.2 martin * send -0 to +0 or +0 to -0, respectively.
533 1.7.6.2 martin */
534 1.7.6.2 martin
535 1.7.6.2 martin CHECK(0, nextafterf, z_neg, +INFINITY, m);
536 1.7.6.2 martin CHECK(1, nexttowardf, z_neg, +INFINITY, m);
537 1.7.6.2 martin CHECK(2, nextafterf, z_pos, +INFINITY, m);
538 1.7.6.2 martin CHECK(3, nexttowardf, z_pos, +INFINITY, m);
539 1.7.6.2 martin
540 1.7.6.2 martin CHECK(4, nextafterf, z_pos, -INFINITY, -m);
541 1.7.6.2 martin CHECK(5, nexttowardf, z_pos, -INFINITY, -m);
542 1.7.6.2 martin CHECK(6, nextafterf, z_neg, -INFINITY, -m);
543 1.7.6.2 martin CHECK(7, nexttowardf, z_neg, -INFINITY, -m);
544 1.7.6.2 martin
545 1.7.6.2 martin /*
546 1.7.6.2 martin * `If x is the negative number of least magnitude in x's
547 1.7.6.2 martin * format, nextUp(x) is -0.'
548 1.7.6.2 martin * --IEEE 754-2019, 5.3.1 General operations, p. 19
549 1.7.6.2 martin */
550 1.7.6.2 martin CHECK(8, nextafterf, -m, +INFINITY, 0);
551 1.7.6.2 martin CHECK(9, nexttowardf, -m, +INFINITY, 0);
552 1.7.6.2 martin ATF_CHECK(signbit(nextafterf(-m, +INFINITY)) != 0);
553 1.7.6.2 martin CHECK(10, nextafterf, m, -INFINITY, 0);
554 1.7.6.2 martin CHECK(11, nexttowardf, m, -INFINITY, 0);
555 1.7.6.2 martin ATF_CHECK(signbit(nextafterf(m, -INFINITY)) == 0);
556 1.7.6.2 martin }
557 1.7.6.2 martin
558 1.7.6.2 martin ATF_TC(nextf_near_0);
559 1.7.6.2 martin ATF_TC_HEAD(nextf_near_0, tc)
560 1.7.6.2 martin {
561 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 0");
562 1.7.6.2 martin }
563 1.7.6.2 martin ATF_TC_BODY(nextf_near_0, tc)
564 1.7.6.2 martin {
565 1.7.6.2 martin static const float x[] = {
566 1.7.6.2 martin [0] = 0,
567 1.7.6.2 martin #ifdef __FLT_HAS_DENORM__
568 1.7.6.2 martin [1] = __FLT_DENORM_MIN__,
569 1.7.6.2 martin [2] = 2*__FLT_DENORM_MIN__,
570 1.7.6.2 martin [3] = 3*__FLT_DENORM_MIN__,
571 1.7.6.2 martin [4] = 4*__FLT_DENORM_MIN__,
572 1.7.6.2 martin #else
573 1.7.6.2 martin [1] = FLT_MIN,
574 1.7.6.2 martin [2] = FLT_MIN*(1 + FLT_EPSILON),
575 1.7.6.2 martin [3] = FLT_MIN*(1 + 2*FLT_EPSILON),
576 1.7.6.2 martin [4] = FLT_MIN*(1 + 3*FLT_EPSILON),
577 1.7.6.2 martin #endif
578 1.7.6.2 martin };
579 1.7.6.2 martin
580 1.7.6.2 martin checkf(x, __arraycount(x));
581 1.7.6.2 martin }
582 1.7.6.2 martin
583 1.7.6.2 martin ATF_TC(nextf_near_sub_normal);
584 1.7.6.2 martin ATF_TC_HEAD(nextf_near_sub_normal, tc)
585 1.7.6.2 martin {
586 1.7.6.2 martin atf_tc_set_md_var(tc, "descr",
587 1.7.6.2 martin "nextafterf/nexttowardf near the subnormal/normal boundary");
588 1.7.6.2 martin }
589 1.7.6.2 martin ATF_TC_BODY(nextf_near_sub_normal, tc)
590 1.7.6.2 martin {
591 1.7.6.2 martin #ifdef __FLT_HAS_DENORM__
592 1.7.6.2 martin static const float x[] = {
593 1.7.6.2 martin [0] = FLT_MIN - 3*__FLT_DENORM_MIN__,
594 1.7.6.2 martin [1] = FLT_MIN - 2*__FLT_DENORM_MIN__,
595 1.7.6.2 martin [2] = FLT_MIN - __FLT_DENORM_MIN__,
596 1.7.6.2 martin [3] = FLT_MIN,
597 1.7.6.2 martin [4] = FLT_MIN + __FLT_DENORM_MIN__,
598 1.7.6.2 martin [5] = FLT_MIN + 2*__FLT_DENORM_MIN__,
599 1.7.6.2 martin [6] = FLT_MIN + 3*__FLT_DENORM_MIN__,
600 1.7.6.2 martin };
601 1.7.6.2 martin
602 1.7.6.2 martin checkf(x, __arraycount(x));
603 1.7.6.2 martin #else /* !__FLT_HAS_DENORM__ */
604 1.7.6.2 martin atf_tc_skip("no subnormals on this architecture");
605 1.7.6.2 martin #endif /* !__FLT_HAS_DENORM__ */
606 1.7.6.2 martin }
607 1.7.6.2 martin
608 1.7.6.2 martin ATF_TC(nextf_near_1);
609 1.7.6.2 martin ATF_TC_HEAD(nextf_near_1, tc)
610 1.7.6.2 martin {
611 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 1");
612 1.7.6.2 martin }
613 1.7.6.2 martin ATF_TC_BODY(nextf_near_1, tc)
614 1.7.6.2 martin {
615 1.7.6.2 martin static const float x[] = {
616 1.7.6.2 martin [0] = 1 - 3*FLT_EPSILON/2,
617 1.7.6.2 martin [1] = 1 - 2*FLT_EPSILON/2,
618 1.7.6.2 martin [2] = 1 - FLT_EPSILON/2,
619 1.7.6.2 martin [3] = 1,
620 1.7.6.2 martin [4] = 1 + FLT_EPSILON,
621 1.7.6.2 martin [5] = 1 + 2*FLT_EPSILON,
622 1.7.6.2 martin [6] = 1 + 3*FLT_EPSILON,
623 1.7.6.2 martin };
624 1.7.6.2 martin
625 1.7.6.2 martin checkf(x, __arraycount(x));
626 1.7.6.2 martin }
627 1.7.6.2 martin
628 1.7.6.2 martin ATF_TC(nextf_near_1_5);
629 1.7.6.2 martin ATF_TC_HEAD(nextf_near_1_5, tc)
630 1.7.6.2 martin {
631 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 1.5");
632 1.7.6.2 martin }
633 1.7.6.2 martin ATF_TC_BODY(nextf_near_1_5, tc)
634 1.7.6.2 martin {
635 1.7.6.2 martin static const float x[] = {
636 1.7.6.2 martin [0] = 1.5 - 3*FLT_EPSILON,
637 1.7.6.2 martin [1] = 1.5 - 2*FLT_EPSILON,
638 1.7.6.2 martin [2] = 1.5 - FLT_EPSILON,
639 1.7.6.2 martin [3] = 1.5,
640 1.7.6.2 martin [4] = 1.5 + FLT_EPSILON,
641 1.7.6.2 martin [5] = 1.5 + 2*FLT_EPSILON,
642 1.7.6.2 martin [6] = 1.5 + 3*FLT_EPSILON,
643 1.7.6.2 martin };
644 1.7.6.2 martin
645 1.7.6.2 martin checkf(x, __arraycount(x));
646 1.7.6.2 martin }
647 1.7.6.2 martin
648 1.7.6.2 martin ATF_TC(nextf_near_infinity);
649 1.7.6.2 martin ATF_TC_HEAD(nextf_near_infinity, tc)
650 1.7.6.2 martin {
651 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near infinity");
652 1.7.6.2 martin }
653 1.7.6.2 martin ATF_TC_BODY(nextf_near_infinity, tc)
654 1.7.6.2 martin {
655 1.7.6.2 martin static const float x[] = {
656 1.7.6.2 martin [0] = FLT_MAX,
657 1.7.6.2 martin [1] = INFINITY,
658 1.7.6.2 martin };
659 1.7.6.2 martin volatile float t;
660 1.7.6.2 martin
661 1.7.6.2 martin if (!isinf(INFINITY))
662 1.7.6.2 martin atf_tc_skip("no infinities on this architecture");
663 1.7.6.2 martin
664 1.7.6.2 martin checkf(x, __arraycount(x));
665 1.7.6.2 martin
666 1.7.6.2 martin ATF_CHECK_EQ_MSG((t = nextafterf(INFINITY, INFINITY)), INFINITY,
667 1.7.6.2 martin "t=%a=%g", t, t);
668 1.7.6.2 martin ATF_CHECK_EQ_MSG((t = nextafterf(-INFINITY, -INFINITY)), -INFINITY,
669 1.7.6.2 martin "t=%a=%g", t, t);
670 1.7.6.2 martin }
671 1.7.6.2 martin
672 1.7.6.2 martin ATF_TC(nextl_nan);
673 1.7.6.2 martin ATF_TC_HEAD(nextl_nan, tc)
674 1.7.6.2 martin {
675 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl on NaN");
676 1.7.6.2 martin }
677 1.7.6.2 martin ATF_TC_BODY(nextl_nan, tc)
678 1.7.6.2 martin {
679 1.7.6.2 martin #ifdef NAN
680 1.7.6.2 martin /* XXX verify the NaN is quiet */
681 1.7.6.2 martin ATF_CHECK(isnan(nextafterl(NAN, 0)));
682 1.7.6.2 martin ATF_CHECK(isnan(nexttowardl(NAN, 0)));
683 1.7.6.2 martin ATF_CHECK(isnan(nextafterl(0, NAN)));
684 1.7.6.2 martin ATF_CHECK(isnan(nexttowardl(0, NAN)));
685 1.7.6.2 martin #else
686 1.7.6.2 martin atf_tc_skip("no NaNs on this architecture");
687 1.7.6.2 martin #endif
688 1.7.6.2 martin }
689 1.7.6.2 martin
690 1.7.6.2 martin ATF_TC(nextl_signed_0);
691 1.7.6.2 martin ATF_TC_HEAD(nextl_signed_0, tc)
692 1.7.6.2 martin {
693 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl on signed 0");
694 1.7.6.2 martin }
695 1.7.6.2 martin ATF_TC_BODY(nextl_signed_0, tc)
696 1.7.6.2 martin {
697 1.7.6.2 martin volatile long double z_pos = +0.;
698 1.7.6.2 martin volatile long double z_neg = -0.;
699 1.7.6.2 martin #ifdef __LDBL_HAS_DENORM__
700 1.7.6.2 martin volatile long double m = __LDBL_DENORM_MIN__;
701 1.7.6.2 martin #else
702 1.7.6.2 martin volatile long double m = LDBL_MIN;
703 1.7.6.2 martin #endif
704 1.7.6.2 martin
705 1.7.6.2 martin if (signbit(z_pos) == signbit(z_neg))
706 1.7.6.2 martin atf_tc_skip("no signed zeroes on this architecture");
707 1.7.6.2 martin
708 1.7.6.2 martin /*
709 1.7.6.2 martin * `nextUp(x) is the least floating-point number in the format
710 1.7.6.2 martin * of x that compares greater than x. [...] nextDown(x) is
711 1.7.6.2 martin * -nextUp(-x).'
712 1.7.6.2 martin * --IEEE 754-2019, 5.3.1 General operations, p. 19
713 1.7.6.2 martin *
714 1.7.6.2 martin * Verify that nextafterl and nexttowardl, which implement the
715 1.7.6.2 martin * nextUp and nextDown operations, obey this rule and don't
716 1.7.6.2 martin * send -0 to +0 or +0 to -0, respectively.
717 1.7.6.2 martin */
718 1.7.6.2 martin
719 1.7.6.2 martin CHECK(0, nextafterl, z_neg, +INFINITY, m);
720 1.7.6.2 martin CHECK(1, nexttowardl, z_neg, +INFINITY, m);
721 1.7.6.2 martin CHECK(2, nextafterl, z_pos, +INFINITY, m);
722 1.7.6.2 martin CHECK(3, nexttowardl, z_pos, +INFINITY, m);
723 1.7.6.2 martin
724 1.7.6.2 martin CHECK(4, nextafterl, z_pos, -INFINITY, -m);
725 1.7.6.2 martin CHECK(5, nexttowardl, z_pos, -INFINITY, -m);
726 1.7.6.2 martin CHECK(6, nextafterl, z_neg, -INFINITY, -m);
727 1.7.6.2 martin CHECK(7, nexttowardl, z_neg, -INFINITY, -m);
728 1.7.6.2 martin
729 1.7.6.2 martin /*
730 1.7.6.2 martin * `If x is the negative number of least magnitude in x's
731 1.7.6.2 martin * format, nextUp(x) is -0.'
732 1.7.6.2 martin * --IEEE 754-2019, 5.3.1 General operations, p. 19
733 1.7.6.2 martin */
734 1.7.6.2 martin CHECK(8, nextafterl, -m, +INFINITY, 0);
735 1.7.6.2 martin CHECK(9, nexttowardl, -m, +INFINITY, 0);
736 1.7.6.2 martin ATF_CHECK(signbit(nextafterl(-m, +INFINITY)) != 0);
737 1.7.6.2 martin CHECK(10, nextafterl, m, -INFINITY, 0);
738 1.7.6.2 martin CHECK(11, nexttowardl, m, -INFINITY, 0);
739 1.7.6.2 martin ATF_CHECK(signbit(nextafterl(m, -INFINITY)) == 0);
740 1.7.6.2 martin }
741 1.7.6.2 martin
742 1.7.6.2 martin ATF_TC(nextl_near_0);
743 1.7.6.2 martin ATF_TC_HEAD(nextl_near_0, tc)
744 1.7.6.2 martin {
745 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 0");
746 1.7.6.2 martin }
747 1.7.6.2 martin ATF_TC_BODY(nextl_near_0, tc)
748 1.7.6.2 martin {
749 1.7.6.2 martin static const long double x[] = {
750 1.7.6.2 martin [0] = 0,
751 1.7.6.2 martin #ifdef __LDBL_HAS_DENORM__
752 1.7.6.2 martin [1] = __LDBL_DENORM_MIN__,
753 1.7.6.2 martin [2] = 2*__LDBL_DENORM_MIN__,
754 1.7.6.2 martin [3] = 3*__LDBL_DENORM_MIN__,
755 1.7.6.2 martin [4] = 4*__LDBL_DENORM_MIN__,
756 1.7.6.2 martin #else
757 1.7.6.2 martin [1] = LDBL_MIN,
758 1.7.6.2 martin [2] = LDBL_MIN*(1 + LDBL_EPSILON),
759 1.7.6.2 martin [3] = LDBL_MIN*(1 + 2*LDBL_EPSILON),
760 1.7.6.2 martin [4] = LDBL_MIN*(1 + 3*LDBL_EPSILON),
761 1.7.6.2 martin #endif
762 1.7.6.2 martin };
763 1.7.6.2 martin
764 1.7.6.2 martin checkl(x, __arraycount(x));
765 1.7.6.2 martin }
766 1.7.6.2 martin
767 1.7.6.2 martin ATF_TC(nextl_near_sub_normal);
768 1.7.6.2 martin ATF_TC_HEAD(nextl_near_sub_normal, tc)
769 1.7.6.2 martin {
770 1.7.6.2 martin atf_tc_set_md_var(tc, "descr",
771 1.7.6.2 martin "nextafterl/nexttowardl near the subnormal/normal boundary");
772 1.7.6.2 martin }
773 1.7.6.2 martin ATF_TC_BODY(nextl_near_sub_normal, tc)
774 1.7.6.2 martin {
775 1.7.6.2 martin #ifdef __LDBL_HAS_DENORM__
776 1.7.6.2 martin static const long double x[] = {
777 1.7.6.2 martin [0] = LDBL_MIN - 3*__LDBL_DENORM_MIN__,
778 1.7.6.2 martin [1] = LDBL_MIN - 2*__LDBL_DENORM_MIN__,
779 1.7.6.2 martin [2] = LDBL_MIN - __LDBL_DENORM_MIN__,
780 1.7.6.2 martin [3] = LDBL_MIN,
781 1.7.6.2 martin [4] = LDBL_MIN + __LDBL_DENORM_MIN__,
782 1.7.6.2 martin [5] = LDBL_MIN + 2*__LDBL_DENORM_MIN__,
783 1.7.6.2 martin [6] = LDBL_MIN + 3*__LDBL_DENORM_MIN__,
784 1.7.6.2 martin };
785 1.7.6.2 martin
786 1.7.6.2 martin checkl(x, __arraycount(x));
787 1.7.6.2 martin #else /* !__LDBL_HAS_DENORM__ */
788 1.7.6.2 martin atf_tc_skip("no subnormals on this architecture");
789 1.7.6.2 martin #endif /* !__LDBL_HAS_DENORM__ */
790 1.7.6.2 martin }
791 1.7.6.2 martin
792 1.7.6.2 martin ATF_TC(nextl_near_1);
793 1.7.6.2 martin ATF_TC_HEAD(nextl_near_1, tc)
794 1.7.6.2 martin {
795 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 1");
796 1.7.6.2 martin }
797 1.7.6.2 martin ATF_TC_BODY(nextl_near_1, tc)
798 1.7.6.2 martin {
799 1.7.6.2 martin static const long double x[] = {
800 1.7.6.2 martin [0] = 1 - 3*LDBL_EPSILON/2,
801 1.7.6.2 martin [1] = 1 - 2*LDBL_EPSILON/2,
802 1.7.6.2 martin [2] = 1 - LDBL_EPSILON/2,
803 1.7.6.2 martin [3] = 1,
804 1.7.6.2 martin [4] = 1 + LDBL_EPSILON,
805 1.7.6.2 martin [5] = 1 + 2*LDBL_EPSILON,
806 1.7.6.2 martin [6] = 1 + 3*LDBL_EPSILON,
807 1.7.6.2 martin };
808 1.7.6.2 martin
809 1.7.6.2 martin checkl(x, __arraycount(x));
810 1.7.6.2 martin }
811 1.7.6.2 martin
812 1.7.6.2 martin ATF_TC(nextl_near_1_5);
813 1.7.6.2 martin ATF_TC_HEAD(nextl_near_1_5, tc)
814 1.7.6.2 martin {
815 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 1.5");
816 1.7.6.2 martin }
817 1.7.6.2 martin ATF_TC_BODY(nextl_near_1_5, tc)
818 1.7.6.2 martin {
819 1.7.6.2 martin static const long double x[] = {
820 1.7.6.2 martin [0] = 1.5 - 3*LDBL_EPSILON,
821 1.7.6.2 martin [1] = 1.5 - 2*LDBL_EPSILON,
822 1.7.6.2 martin [2] = 1.5 - LDBL_EPSILON,
823 1.7.6.2 martin [3] = 1.5,
824 1.7.6.2 martin [4] = 1.5 + LDBL_EPSILON,
825 1.7.6.2 martin [5] = 1.5 + 2*LDBL_EPSILON,
826 1.7.6.2 martin [6] = 1.5 + 3*LDBL_EPSILON,
827 1.7.6.2 martin };
828 1.7.6.2 martin
829 1.7.6.2 martin checkl(x, __arraycount(x));
830 1.7.6.2 martin }
831 1.7.6.2 martin
832 1.7.6.2 martin ATF_TC(nextl_near_infinity);
833 1.7.6.2 martin ATF_TC_HEAD(nextl_near_infinity, tc)
834 1.7.6.2 martin {
835 1.7.6.2 martin atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near infinity");
836 1.7.6.2 martin }
837 1.7.6.2 martin ATF_TC_BODY(nextl_near_infinity, tc)
838 1.7.6.2 martin {
839 1.7.6.2 martin static const long double x[] = {
840 1.7.6.2 martin [0] = LDBL_MAX,
841 1.7.6.2 martin [1] = INFINITY,
842 1.7.6.2 martin };
843 1.7.6.2 martin volatile long double t;
844 1.7.6.2 martin
845 1.7.6.2 martin if (!isinf(INFINITY))
846 1.7.6.2 martin atf_tc_skip("no infinities on this architecture");
847 1.7.6.2 martin
848 1.7.6.2 martin checkl(x, __arraycount(x));
849 1.7.6.2 martin
850 1.7.6.2 martin ATF_CHECK_EQ_MSG((t = nextafterl(INFINITY, INFINITY)), INFINITY,
851 1.7.6.2 martin "t=%La=%Lg", t, t);
852 1.7.6.2 martin ATF_CHECK_EQ_MSG((t = nextafterl(-INFINITY, -INFINITY)), -INFINITY,
853 1.7.6.2 martin "t=%La=%Lg", t, t);
854 1.7.6.2 martin }
855 1.7.6.2 martin
856 1.7.6.2 martin #endif /* __vax__ */
857 1.7.6.2 martin
858 1.7.6.2 martin ATF_TP_ADD_TCS(tp)
859 1.7.6.2 martin {
860 1.7.6.2 martin
861 1.7.6.2 martin #ifdef __vax__
862 1.7.6.2 martin ATF_TP_ADD_TC(tp, vaxafter);
863 1.7.6.2 martin #else
864 1.7.6.2 martin ATF_TP_ADD_TC(tp, next_nan);
865 1.7.6.2 martin ATF_TP_ADD_TC(tp, next_near_0);
866 1.7.6.2 martin ATF_TP_ADD_TC(tp, next_near_1);
867 1.7.6.2 martin ATF_TP_ADD_TC(tp, next_near_1_5);
868 1.7.6.2 martin ATF_TP_ADD_TC(tp, next_near_infinity);
869 1.7.6.2 martin ATF_TP_ADD_TC(tp, next_near_sub_normal);
870 1.7.6.2 martin ATF_TP_ADD_TC(tp, next_signed_0);
871 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextf_nan);
872 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextf_near_0);
873 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextf_near_1);
874 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextf_near_1_5);
875 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextf_near_infinity);
876 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextf_near_sub_normal);
877 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextf_signed_0);
878 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextl_nan);
879 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextl_near_0);
880 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextl_near_1);
881 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextl_near_1_5);
882 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextl_near_infinity);
883 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextl_near_sub_normal);
884 1.7.6.2 martin ATF_TP_ADD_TC(tp, nextl_signed_0);
885 1.7.6.2 martin #endif
886 1.7.6.2 martin return atf_no_error();
887 1.7.6.2 martin }
888