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