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