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
38ATF_TC(vaxafter);
39ATF_TC_HEAD(vaxafter, tc)
40{
41
42	atf_tc_set_md_var(tc, "descr", "vax nextafter/nexttoward reminder");
43}
44ATF_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 */
75static void
76check(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 */
157static void
158checkf(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 */
238static void
239checkl(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
301ATF_TC(next_nan);
302ATF_TC_HEAD(next_nan, tc)
303{
304	atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward on NaN");
305}
306ATF_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
319ATF_TC(next_signed_0);
320ATF_TC_HEAD(next_signed_0, tc)
321{
322	atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward on signed 0");
323}
324ATF_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
374ATF_TC(next_near_0);
375ATF_TC_HEAD(next_near_0, tc)
376{
377	atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 0");
378}
379ATF_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
399ATF_TC(next_near_sub_normal);
400ATF_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}
405ATF_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
424ATF_TC(next_near_1);
425ATF_TC_HEAD(next_near_1, tc)
426{
427	atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 1");
428}
429ATF_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
444ATF_TC(next_near_1_5);
445ATF_TC_HEAD(next_near_1_5, tc)
446{
447	atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 1.5");
448}
449ATF_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
464ATF_TC(next_near_infinity);
465ATF_TC_HEAD(next_near_infinity, tc)
466{
467	atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near infinity");
468}
469ATF_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
488ATF_TC(nextf_nan);
489ATF_TC_HEAD(nextf_nan, tc)
490{
491	atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf on NaN");
492}
493ATF_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
506ATF_TC(nextf_signed_0);
507ATF_TC_HEAD(nextf_signed_0, tc)
508{
509	atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf on signed 0");
510}
511ATF_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
558ATF_TC(nextf_near_0);
559ATF_TC_HEAD(nextf_near_0, tc)
560{
561	atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 0");
562}
563ATF_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
583ATF_TC(nextf_near_sub_normal);
584ATF_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}
589ATF_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
608ATF_TC(nextf_near_1);
609ATF_TC_HEAD(nextf_near_1, tc)
610{
611	atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 1");
612}
613ATF_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
628ATF_TC(nextf_near_1_5);
629ATF_TC_HEAD(nextf_near_1_5, tc)
630{
631	atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 1.5");
632}
633ATF_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
648ATF_TC(nextf_near_infinity);
649ATF_TC_HEAD(nextf_near_infinity, tc)
650{
651	atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near infinity");
652}
653ATF_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
672ATF_TC(nextl_nan);
673ATF_TC_HEAD(nextl_nan, tc)
674{
675	atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl on NaN");
676}
677ATF_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
690ATF_TC(nextl_signed_0);
691ATF_TC_HEAD(nextl_signed_0, tc)
692{
693	atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl on signed 0");
694}
695ATF_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
742ATF_TC(nextl_near_0);
743ATF_TC_HEAD(nextl_near_0, tc)
744{
745	atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 0");
746}
747ATF_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
767ATF_TC(nextl_near_sub_normal);
768ATF_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}
773ATF_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
792ATF_TC(nextl_near_1);
793ATF_TC_HEAD(nextl_near_1, tc)
794{
795	atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 1");
796}
797ATF_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
812ATF_TC(nextl_near_1_5);
813ATF_TC_HEAD(nextl_near_1_5, tc)
814{
815	atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 1.5");
816}
817ATF_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
832ATF_TC(nextl_near_infinity);
833ATF_TC_HEAD(nextl_near_infinity, tc)
834{
835	atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near infinity");
836}
837ATF_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
858ATF_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