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); 39 ATF_TC_HEAD(vaxafter, tc) 40 { 41 42 atf_tc_set_md_var(tc, "descr", "vax nextafter/nexttoward reminder"); 43 } 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 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 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 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); 302 ATF_TC_HEAD(next_nan, tc) 303 { 304 atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward on NaN"); 305 } 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); 320 ATF_TC_HEAD(next_signed_0, tc) 321 { 322 atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward on signed 0"); 323 } 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); 375 ATF_TC_HEAD(next_near_0, tc) 376 { 377 atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 0"); 378 } 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); 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 } 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); 425 ATF_TC_HEAD(next_near_1, tc) 426 { 427 atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 1"); 428 } 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); 445 ATF_TC_HEAD(next_near_1_5, tc) 446 { 447 atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near 1.5"); 448 } 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); 465 ATF_TC_HEAD(next_near_infinity, tc) 466 { 467 atf_tc_set_md_var(tc, "descr", "nextafter/nexttoward near infinity"); 468 } 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); 489 ATF_TC_HEAD(nextf_nan, tc) 490 { 491 atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf on NaN"); 492 } 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); 507 ATF_TC_HEAD(nextf_signed_0, tc) 508 { 509 atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf on signed 0"); 510 } 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); 559 ATF_TC_HEAD(nextf_near_0, tc) 560 { 561 atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 0"); 562 } 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); 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 } 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); 609 ATF_TC_HEAD(nextf_near_1, tc) 610 { 611 atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 1"); 612 } 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); 629 ATF_TC_HEAD(nextf_near_1_5, tc) 630 { 631 atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near 1.5"); 632 } 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); 649 ATF_TC_HEAD(nextf_near_infinity, tc) 650 { 651 atf_tc_set_md_var(tc, "descr", "nextafterf/nexttowardf near infinity"); 652 } 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); 673 ATF_TC_HEAD(nextl_nan, tc) 674 { 675 atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl on NaN"); 676 } 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); 691 ATF_TC_HEAD(nextl_signed_0, tc) 692 { 693 atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl on signed 0"); 694 } 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); 743 ATF_TC_HEAD(nextl_near_0, tc) 744 { 745 atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 0"); 746 } 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); 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 } 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); 793 ATF_TC_HEAD(nextl_near_1, tc) 794 { 795 atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 1"); 796 } 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); 813 ATF_TC_HEAD(nextl_near_1_5, tc) 814 { 815 atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near 1.5"); 816 } 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); 833 ATF_TC_HEAD(nextl_near_infinity, tc) 834 { 835 atf_tc_set_md_var(tc, "descr", "nextafterl/nexttowardl near infinity"); 836 } 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 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