1/* $NetBSD: t_hypot.c,v 1.8 2024/05/13 20:28:15 rillig Exp $ */ 2 3/*- 4 * Copyright (c) 2016 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 <atf-c.h> 30#include <float.h> 31#include <math.h> 32 33#define CHECK_EQ(i, hypot, a, b, c) \ 34 ATF_CHECK_MSG(hypot(a, b) == (c), \ 35 "[%u] %s(%a, %a)=%a, expected %a", \ 36 (i), #hypot, (a), (b), hypot(a, b), (c)) 37 38#define CHECKL_EQ(i, hypot, a, b, c) \ 39 ATF_CHECK_MSG(hypot(a, b) == (c), \ 40 "[%u] %s(%La, %La)=%La, expected %La", \ 41 (i), #hypot, (long double)(a), (long double)(b), hypot(a, b), \ 42 (long double)(c)) 43 44#define CHECK_NAN(i, hypot, a, b) \ 45 ATF_CHECK_MSG(isnan(hypot(a, b)), \ 46 "[%u] %s(%a, %a)=%a, expected NaN", \ 47 (i), #hypot, (a), (b), hypot(a, b)) 48 49#define CHECKL_NAN(i, hypot, a, b) \ 50 ATF_CHECK_MSG(isnan(hypot(a, b)), \ 51 "[%u] %s(%La, %La)=%La, expected NaN", \ 52 (i), #hypot, (long double)(a), (long double)(b), hypot(a, b)) 53 54static const float trivial_casesf[] = { 55 0, 56#ifdef __FLT_HAS_DENORM__ 57 __FLT_DENORM_MIN__, 58 2*__FLT_DENORM_MIN__, 59 3*__FLT_DENORM_MIN__, 60 FLT_MIN - 3*__FLT_DENORM_MIN__, 61 FLT_MIN - 2*__FLT_DENORM_MIN__, 62 FLT_MIN - __FLT_DENORM_MIN__, 63#endif 64 FLT_MIN, 65 FLT_MIN*(1 + FLT_EPSILON), 66 FLT_MIN*(1 + 2*FLT_EPSILON), 67 2*FLT_MIN, 68 FLT_EPSILON/2, 69 FLT_EPSILON, 70 2*FLT_EPSILON, 71 1 - 3*FLT_EPSILON/2, 72 1 - 2*FLT_EPSILON/2, 73 1 - FLT_EPSILON/2, 74 1, 75 1 + FLT_EPSILON, 76 1 + 2*FLT_EPSILON, 77 1 + 3*FLT_EPSILON, 78 1.5 - 3*FLT_EPSILON, 79 1.5 - 2*FLT_EPSILON, 80 1.5 - FLT_EPSILON, 81 1.5, 82 1.5 + FLT_EPSILON, 83 1.5 + 2*FLT_EPSILON, 84 1.5 + 3*FLT_EPSILON, 85 2, 86 0.5/FLT_EPSILON - 0.5, 87 0.5/FLT_EPSILON, 88 0.5/FLT_EPSILON + 0.5, 89 1/FLT_EPSILON, 90 FLT_MAX, 91 INFINITY, 92}; 93 94static const double trivial_cases[] = { 95 0, 96#ifdef __DBL_HAS_DENORM__ 97 __DBL_DENORM_MIN__, 98 2*__DBL_DENORM_MIN__, 99 3*__DBL_DENORM_MIN__, 100 DBL_MIN - 3*__DBL_DENORM_MIN__, 101 DBL_MIN - 2*__DBL_DENORM_MIN__, 102 DBL_MIN - __DBL_DENORM_MIN__, 103#endif 104 DBL_MIN, 105 DBL_MIN*(1 + DBL_EPSILON), 106 DBL_MIN*(1 + 2*DBL_EPSILON), 107 2*DBL_MIN, 108 DBL_EPSILON/2, 109 DBL_EPSILON, 110 2*DBL_EPSILON, 111 1 - 3*DBL_EPSILON/2, 112 1 - 2*DBL_EPSILON/2, 113 1 - DBL_EPSILON/2, 114 1, 115 1 + DBL_EPSILON, 116 1 + 2*DBL_EPSILON, 117 1 + 3*DBL_EPSILON, 118 1.5 - 3*DBL_EPSILON, 119 1.5 - 2*DBL_EPSILON, 120 1.5 - DBL_EPSILON, 121 1.5, 122 1.5 + DBL_EPSILON, 123 1.5 + 2*DBL_EPSILON, 124 1.5 + 3*DBL_EPSILON, 125 2, 126 1/FLT_EPSILON - 0.5, 127 1/FLT_EPSILON, 128 1/FLT_EPSILON + 0.5, 129 0.5/DBL_EPSILON - 0.5, 130 0.5/DBL_EPSILON, 131 0.5/DBL_EPSILON + 0.5, 132 1/DBL_EPSILON, 133 DBL_MAX, 134 INFINITY, 135}; 136 137static const long double trivial_casesl[] = { 138 0, 139#ifdef __LDBL_HAS_DENORM__ 140 __LDBL_DENORM_MIN__, 141 2*__LDBL_DENORM_MIN__, 142 3*__LDBL_DENORM_MIN__, 143 LDBL_MIN - 3*__LDBL_DENORM_MIN__, 144 LDBL_MIN - 2*__LDBL_DENORM_MIN__, 145 LDBL_MIN - __LDBL_DENORM_MIN__, 146#endif 147 LDBL_MIN, 148 LDBL_MIN*(1 + LDBL_EPSILON), 149 LDBL_MIN*(1 + 2*LDBL_EPSILON), 150 2*LDBL_MIN, 151 LDBL_EPSILON/2, 152 LDBL_EPSILON, 153 2*LDBL_EPSILON, 154 1 - 3*LDBL_EPSILON/2, 155 1 - 2*LDBL_EPSILON/2, 156 1 - LDBL_EPSILON/2, 157 1, 158 1 + LDBL_EPSILON, 159 1 + 2*LDBL_EPSILON, 160 1 + 3*LDBL_EPSILON, 161 1.5 - 3*LDBL_EPSILON, 162 1.5 - 2*LDBL_EPSILON, 163 1.5 - LDBL_EPSILON, 164 1.5, 165 1.5 + LDBL_EPSILON, 166 1.5 + 2*LDBL_EPSILON, 167 1.5 + 3*LDBL_EPSILON, 168 2, 169 1/FLT_EPSILON - 0.5, 170 1/FLT_EPSILON, 171 1/FLT_EPSILON + 0.5, 172#ifdef __HAVE_LONG_DOUBLE 173 1/DBL_EPSILON - 0.5L, 174 1/DBL_EPSILON, 175 1/DBL_EPSILON + 0.5L, 176#endif 177 0.5/LDBL_EPSILON - 0.5, 178 0.5/LDBL_EPSILON, 179 0.5/LDBL_EPSILON + 0.5, 180 1/LDBL_EPSILON, 181 LDBL_MAX, 182 INFINITY, 183}; 184 185ATF_TC(hypotf_trivial); 186ATF_TC_HEAD(hypotf_trivial, tc) 187{ 188 atf_tc_set_md_var(tc, "descr", "hypotf(x,0) and hypotf(0,x)"); 189} 190ATF_TC_BODY(hypotf_trivial, tc) 191{ 192 unsigned i; 193 194 for (i = 0; i < __arraycount(trivial_casesf); i++) { 195 volatile float x = trivial_casesf[i]; 196 197 CHECK_EQ(i, hypotf, x, +0., x); 198 CHECK_EQ(i, hypotf, x, -0., x); 199 CHECK_EQ(i, hypotf, +0., x, x); 200 CHECK_EQ(i, hypotf, -0., x, x); 201 CHECK_EQ(i, hypotf, -x, +0., x); 202 CHECK_EQ(i, hypotf, -x, -0., x); 203 CHECK_EQ(i, hypotf, +0., -x, x); 204 CHECK_EQ(i, hypotf, -0., -x, x); 205 206 if (isinf(INFINITY)) { 207 CHECK_EQ(i, hypotf, x, +INFINITY, INFINITY); 208 CHECK_EQ(i, hypotf, x, -INFINITY, INFINITY); 209 CHECK_EQ(i, hypotf, +INFINITY, x, INFINITY); 210 CHECK_EQ(i, hypotf, -INFINITY, x, INFINITY); 211 CHECK_EQ(i, hypotf, -x, +INFINITY, INFINITY); 212 CHECK_EQ(i, hypotf, -x, -INFINITY, INFINITY); 213 CHECK_EQ(i, hypotf, +INFINITY, -x, INFINITY); 214 CHECK_EQ(i, hypotf, -INFINITY, -x, INFINITY); 215 } 216 217#ifdef NAN 218 if (isinf(x)) { 219 CHECK_EQ(i, hypotf, x, NAN, INFINITY); 220 CHECK_EQ(i, hypotf, NAN, x, INFINITY); 221 CHECK_EQ(i, hypotf, -x, NAN, INFINITY); 222 CHECK_EQ(i, hypotf, NAN, -x, INFINITY); 223 } else { 224 CHECK_NAN(i, hypotf, x, NAN); 225 CHECK_NAN(i, hypotf, NAN, x); 226 CHECK_NAN(i, hypotf, -x, NAN); 227 CHECK_NAN(i, hypotf, NAN, -x); 228 } 229#endif 230 } 231} 232 233ATF_TC(hypot_trivial); 234ATF_TC_HEAD(hypot_trivial, tc) 235{ 236 atf_tc_set_md_var(tc, "descr", "hypot(x,0) and hypot(0,x)"); 237} 238ATF_TC_BODY(hypot_trivial, tc) 239{ 240 unsigned i; 241 242 for (i = 0; i < __arraycount(trivial_casesf); i++) { 243 volatile double x = trivial_casesf[i]; 244 245 CHECK_EQ(i, hypot, x, +0., x); 246 CHECK_EQ(i, hypot, x, -0., x); 247 CHECK_EQ(i, hypot, +0., x, x); 248 CHECK_EQ(i, hypot, -0., x, x); 249 CHECK_EQ(i, hypot, -x, +0., x); 250 CHECK_EQ(i, hypot, -x, -0., x); 251 CHECK_EQ(i, hypot, +0., -x, x); 252 CHECK_EQ(i, hypot, -0., -x, x); 253 254 if (isinf(INFINITY)) { 255 CHECK_EQ(i, hypot, x, +INFINITY, INFINITY); 256 CHECK_EQ(i, hypot, x, -INFINITY, INFINITY); 257 CHECK_EQ(i, hypot, +INFINITY, x, INFINITY); 258 CHECK_EQ(i, hypot, -INFINITY, x, INFINITY); 259 CHECK_EQ(i, hypot, -x, +INFINITY, INFINITY); 260 CHECK_EQ(i, hypot, -x, -INFINITY, INFINITY); 261 CHECK_EQ(i, hypot, +INFINITY, -x, INFINITY); 262 CHECK_EQ(i, hypot, -INFINITY, -x, INFINITY); 263 } 264 265#ifdef NAN 266 if (isinf(x)) { 267 CHECK_EQ(i, hypot, x, NAN, INFINITY); 268 CHECK_EQ(i, hypot, NAN, x, INFINITY); 269 CHECK_EQ(i, hypot, -x, NAN, INFINITY); 270 CHECK_EQ(i, hypot, NAN, -x, INFINITY); 271 } else { 272 CHECK_NAN(i, hypot, x, NAN); 273 CHECK_NAN(i, hypot, NAN, x); 274 CHECK_NAN(i, hypot, -x, NAN); 275 CHECK_NAN(i, hypot, NAN, -x); 276 } 277#endif 278 } 279 280 for (i = 0; i < __arraycount(trivial_cases); i++) { 281 volatile double x = trivial_cases[i]; 282 283 CHECK_EQ(i, hypot, x, +0., x); 284 CHECK_EQ(i, hypot, x, -0., x); 285 CHECK_EQ(i, hypot, +0., x, x); 286 CHECK_EQ(i, hypot, -0., x, x); 287 CHECK_EQ(i, hypot, -x, +0., x); 288 CHECK_EQ(i, hypot, -x, -0., x); 289 CHECK_EQ(i, hypot, +0., -x, x); 290 CHECK_EQ(i, hypot, -0., -x, x); 291 292 if (isinf(INFINITY)) { 293 CHECK_EQ(i, hypot, x, +INFINITY, INFINITY); 294 CHECK_EQ(i, hypot, x, -INFINITY, INFINITY); 295 CHECK_EQ(i, hypot, +INFINITY, x, INFINITY); 296 CHECK_EQ(i, hypot, -INFINITY, x, INFINITY); 297 CHECK_EQ(i, hypot, -x, +INFINITY, INFINITY); 298 CHECK_EQ(i, hypot, -x, -INFINITY, INFINITY); 299 CHECK_EQ(i, hypot, +INFINITY, -x, INFINITY); 300 CHECK_EQ(i, hypot, -INFINITY, -x, INFINITY); 301 } 302 303#ifdef NAN 304 if (isinf(x)) { 305 CHECK_EQ(i, hypot, x, NAN, INFINITY); 306 CHECK_EQ(i, hypot, NAN, x, INFINITY); 307 CHECK_EQ(i, hypot, -x, NAN, INFINITY); 308 CHECK_EQ(i, hypot, NAN, -x, INFINITY); 309 } else { 310 CHECK_NAN(i, hypot, x, NAN); 311 CHECK_NAN(i, hypot, NAN, x); 312 CHECK_NAN(i, hypot, -x, NAN); 313 CHECK_NAN(i, hypot, NAN, -x); 314 } 315#endif 316 } 317} 318 319ATF_TC(hypotl_trivial); 320ATF_TC_HEAD(hypotl_trivial, tc) 321{ 322 atf_tc_set_md_var(tc, "descr", "hypotl(x,0) and hypotl(0,x)"); 323} 324ATF_TC_BODY(hypotl_trivial, tc) 325{ 326 unsigned i; 327 328 for (i = 0; i < __arraycount(trivial_casesf); i++) { 329 volatile long double x = trivial_casesf[i]; 330 331 CHECKL_EQ(i, hypotl, x, +0.L, x); 332 CHECKL_EQ(i, hypotl, x, -0.L, x); 333 CHECKL_EQ(i, hypotl, +0.L, x, x); 334 CHECKL_EQ(i, hypotl, -0.L, x, x); 335 CHECKL_EQ(i, hypotl, -x, +0.L, x); 336 CHECKL_EQ(i, hypotl, -x, -0.L, x); 337 CHECKL_EQ(i, hypotl, +0.L, -x, x); 338 CHECKL_EQ(i, hypotl, -0.L, -x, x); 339 340 if (isinf(INFINITY)) { 341 CHECKL_EQ(i, hypotl, x, +INFINITY, INFINITY); 342 CHECKL_EQ(i, hypotl, x, -INFINITY, INFINITY); 343 CHECKL_EQ(i, hypotl, +INFINITY, x, INFINITY); 344 CHECKL_EQ(i, hypotl, -INFINITY, x, INFINITY); 345 CHECKL_EQ(i, hypotl, -x, +INFINITY, INFINITY); 346 CHECKL_EQ(i, hypotl, -x, -INFINITY, INFINITY); 347 CHECKL_EQ(i, hypotl, +INFINITY, -x, INFINITY); 348 CHECKL_EQ(i, hypotl, -INFINITY, -x, INFINITY); 349 } 350 351#ifdef NAN 352 if (isinf(x)) { 353 CHECKL_EQ(i, hypotl, x, NAN, INFINITY); 354 CHECKL_EQ(i, hypotl, NAN, x, INFINITY); 355 CHECKL_EQ(i, hypotl, -x, NAN, INFINITY); 356 CHECKL_EQ(i, hypotl, NAN, -x, INFINITY); 357 } else { 358 CHECKL_NAN(i, hypotl, x, NAN); 359 CHECKL_NAN(i, hypotl, NAN, x); 360 CHECKL_NAN(i, hypotl, -x, NAN); 361 CHECKL_NAN(i, hypotl, NAN, -x); 362 } 363#endif 364 } 365 366 for (i = 0; i < __arraycount(trivial_cases); i++) { 367 volatile long double x = trivial_cases[i]; 368 369 CHECKL_EQ(i, hypotl, x, +0.L, x); 370 CHECKL_EQ(i, hypotl, x, -0.L, x); 371 CHECKL_EQ(i, hypotl, +0.L, x, x); 372 CHECKL_EQ(i, hypotl, -0.L, x, x); 373 CHECKL_EQ(i, hypotl, -x, +0.L, x); 374 CHECKL_EQ(i, hypotl, -x, -0.L, x); 375 CHECKL_EQ(i, hypotl, +0.L, -x, x); 376 CHECKL_EQ(i, hypotl, -0.L, -x, x); 377 378 if (isinf(INFINITY)) { 379 CHECKL_EQ(i, hypotl, x, +INFINITY, INFINITY); 380 CHECKL_EQ(i, hypotl, x, -INFINITY, INFINITY); 381 CHECKL_EQ(i, hypotl, +INFINITY, x, INFINITY); 382 CHECKL_EQ(i, hypotl, -INFINITY, x, INFINITY); 383 CHECKL_EQ(i, hypotl, -x, +INFINITY, INFINITY); 384 CHECKL_EQ(i, hypotl, -x, -INFINITY, INFINITY); 385 CHECKL_EQ(i, hypotl, +INFINITY, -x, INFINITY); 386 CHECKL_EQ(i, hypotl, -INFINITY, -x, INFINITY); 387 } 388 389#ifdef NAN 390 if (isinf(x)) { 391 CHECKL_EQ(i, hypotl, x, NAN, INFINITY); 392 CHECKL_EQ(i, hypotl, NAN, x, INFINITY); 393 CHECKL_EQ(i, hypotl, -x, NAN, INFINITY); 394 CHECKL_EQ(i, hypotl, NAN, -x, INFINITY); 395 } else { 396 CHECKL_NAN(i, hypotl, x, NAN); 397 CHECKL_NAN(i, hypotl, NAN, x); 398 CHECKL_NAN(i, hypotl, -x, NAN); 399 CHECKL_NAN(i, hypotl, NAN, -x); 400 } 401#endif 402 } 403 404 for (i = 0; i < __arraycount(trivial_casesl); i++) { 405 volatile long double x = trivial_casesl[i]; 406 407 CHECKL_EQ(i, hypotl, x, +0.L, x); 408 CHECKL_EQ(i, hypotl, x, -0.L, x); 409 CHECKL_EQ(i, hypotl, +0.L, x, x); 410 CHECKL_EQ(i, hypotl, -0.L, x, x); 411 CHECKL_EQ(i, hypotl, -x, +0.L, x); 412 CHECKL_EQ(i, hypotl, -x, -0.L, x); 413 CHECKL_EQ(i, hypotl, +0.L, -x, x); 414 CHECKL_EQ(i, hypotl, -0.L, -x, x); 415 416 if (isinf(INFINITY)) { 417 CHECKL_EQ(i, hypotl, x, +INFINITY, INFINITY); 418 CHECKL_EQ(i, hypotl, x, -INFINITY, INFINITY); 419 CHECKL_EQ(i, hypotl, +INFINITY, x, INFINITY); 420 CHECKL_EQ(i, hypotl, -INFINITY, x, INFINITY); 421 CHECKL_EQ(i, hypotl, -x, +INFINITY, INFINITY); 422 CHECKL_EQ(i, hypotl, -x, -INFINITY, INFINITY); 423 CHECKL_EQ(i, hypotl, +INFINITY, -x, INFINITY); 424 CHECKL_EQ(i, hypotl, -INFINITY, -x, INFINITY); 425 } 426 427#ifdef NAN 428 if (isinf(x)) { 429 CHECKL_EQ(i, hypotl, x, NAN, INFINITY); 430 CHECKL_EQ(i, hypotl, NAN, x, INFINITY); 431 CHECKL_EQ(i, hypotl, -x, NAN, INFINITY); 432 CHECKL_EQ(i, hypotl, NAN, -x, INFINITY); 433 } else { 434 CHECKL_NAN(i, hypotl, x, NAN); 435 CHECKL_NAN(i, hypotl, NAN, x); 436 CHECKL_NAN(i, hypotl, -x, NAN); 437 CHECKL_NAN(i, hypotl, NAN, -x); 438 } 439#endif 440 } 441} 442 443/* 444 * All primitive Pythagorean triples are generated from coprime 445 * integers m > n > 0 by Euclid's formula, 446 * 447 * a = m^2 - n^2 448 * b = 2 m n, 449 * c = m^2 + n^2. 450 * 451 * We test cases with various different numbers and positions of bits, 452 * generated by this formula. 453 * 454 * If you're curious, you can recover m and n from a, b, and c by 455 * 456 * m = sqrt((a + c)/2) 457 * n = b/2m. 458 */ 459 460__CTASSERT(FLT_MANT_DIG >= 24); 461static const struct { 462 float a, b, c; 463} exact_casesf[] = { 464 { 3, 4, 5 }, 465 { 5, 12, 13 }, 466 { 9, 12, 15 }, 467 { 0x1001, 0x801000, 0x801001 }, 468 { 4248257, 1130976, 4396225 }, 469}; 470 471__CTASSERT(DBL_MANT_DIG >= 53); 472static const struct { 473 double a, b, c; 474} exact_cases[] = { 475 { 3378249543467007, 4505248894795776, 5631148868747265 }, 476 { 0x7ffffff, 0x1ffffff8000000, 0x1ffffff8000001 }, 477#if DBL_MANT_DIG >= 56 478 { 13514123525517439, 18018830919909120, 22523538851237761 }, 479 { 0x1fffffff, 0x1ffffffe0000000, 0x1ffffffe0000001 }, 480#endif 481}; 482 483#if LDBL_MANT_DIG >= 64 484static const struct { 485 long double a, b, c; 486} exact_casesl[] = { 487 { 3458976450080784639, 4611968592949214720, 5764960744407842561 }, 488 { 0x200000000, 0x7ffffffffffffffe, 0x8000000000000002 }, 489#if LDBL_MANT_DIG >= 113 490 { 973555668229277869436257492279295.L, 491 1298074224305703705819019479072768.L, 492 1622592780382129686316970078625793.L }, 493 { 0x1ffffffffffffff, 494 0x1fffffffffffffe00000000000000p0L, 495 0x1fffffffffffffe00000000000001p0L }, 496#endif 497}; 498#endif 499 500ATF_TC(hypotf_exact); 501ATF_TC_HEAD(hypotf_exact, tc) 502{ 503 atf_tc_set_md_var(tc, "descr", "hypotf on scaled Pythagorean triples"); 504} 505ATF_TC_BODY(hypotf_exact, tc) 506{ 507 unsigned i; 508 509 for (i = 0; i < __arraycount(exact_casesf); i++) { 510 int s; 511 512 for (s = FLT_MIN_EXP; 513 s < FLT_MAX_EXP - FLT_MANT_DIG; 514 s += (FLT_MAX_EXP - FLT_MANT_DIG - FLT_MIN_EXP)/5) { 515 volatile double a = ldexpf(exact_casesf[i].a, s); 516 volatile double b = ldexpf(exact_casesf[i].b, s); 517 float c = ldexpf(exact_casesf[i].c, s); 518 519 CHECK_EQ(i, hypot, a, b, c); 520 CHECK_EQ(i, hypot, b, a, c); 521 CHECK_EQ(i, hypot, a, -b, c); 522 CHECK_EQ(i, hypot, b, -a, c); 523 CHECK_EQ(i, hypot, -a, b, c); 524 CHECK_EQ(i, hypot, -b, a, c); 525 CHECK_EQ(i, hypot, -a, -b, c); 526 CHECK_EQ(i, hypot, -b, -a, c); 527 } 528 } 529} 530 531ATF_TC(hypot_exact); 532ATF_TC_HEAD(hypot_exact, tc) 533{ 534 atf_tc_set_md_var(tc, "descr", "hypot on scaled Pythagorean triples"); 535} 536ATF_TC_BODY(hypot_exact, tc) 537{ 538 unsigned i; 539 540 for (i = 0; i < __arraycount(exact_casesf); i++) { 541 int s; 542 543 for (s = DBL_MIN_EXP; 544 s < DBL_MAX_EXP - DBL_MANT_DIG; 545 s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) { 546 volatile double a = ldexp(exact_casesf[i].a, s); 547 volatile double b = ldexp(exact_casesf[i].b, s); 548 double c = ldexp(exact_casesf[i].c, s); 549 550 CHECK_EQ(i, hypot, a, b, c); 551 CHECK_EQ(i, hypot, b, a, c); 552 CHECK_EQ(i, hypot, a, -b, c); 553 CHECK_EQ(i, hypot, b, -a, c); 554 CHECK_EQ(i, hypot, -a, b, c); 555 CHECK_EQ(i, hypot, -b, a, c); 556 CHECK_EQ(i, hypot, -a, -b, c); 557 CHECK_EQ(i, hypot, -b, -a, c); 558 } 559 } 560 561 for (i = 0; i < __arraycount(exact_cases); i++) { 562 int s; 563 564 for (s = DBL_MIN_EXP; 565 s < DBL_MAX_EXP - DBL_MANT_DIG; 566 s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) { 567 volatile double a = ldexp(exact_cases[i].a, s); 568 volatile double b = ldexp(exact_cases[i].b, s); 569 double c = ldexp(exact_cases[i].c, s); 570 571 CHECK_EQ(i, hypot, a, b, c); 572 CHECK_EQ(i, hypot, b, a, c); 573 CHECK_EQ(i, hypot, a, -b, c); 574 CHECK_EQ(i, hypot, b, -a, c); 575 CHECK_EQ(i, hypot, -a, b, c); 576 CHECK_EQ(i, hypot, -b, a, c); 577 CHECK_EQ(i, hypot, -a, -b, c); 578 CHECK_EQ(i, hypot, -b, -a, c); 579 } 580 } 581} 582 583ATF_TC(hypotl_exact); 584ATF_TC_HEAD(hypotl_exact, tc) 585{ 586 atf_tc_set_md_var(tc, "descr", "hypotl on scaled Pythagorean triples"); 587} 588ATF_TC_BODY(hypotl_exact, tc) 589{ 590 unsigned i; 591 592 for (i = 0; i < __arraycount(exact_casesf); i++) { 593 int s; 594 595 for (s = LDBL_MIN_EXP; 596 s < LDBL_MAX_EXP - LDBL_MANT_DIG; 597 s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) { 598 volatile long double a = ldexpl(exact_casesf[i].a, s); 599 volatile long double b = ldexpl(exact_casesf[i].b, s); 600 long double c = ldexpl(exact_casesf[i].c, s); 601 602 CHECKL_EQ(i, hypotl, a, b, c); 603 CHECKL_EQ(i, hypotl, b, a, c); 604 CHECKL_EQ(i, hypotl, a, -b, c); 605 CHECKL_EQ(i, hypotl, b, -a, c); 606 CHECKL_EQ(i, hypotl, -a, b, c); 607 CHECKL_EQ(i, hypotl, -b, a, c); 608 CHECKL_EQ(i, hypotl, -a, -b, c); 609 CHECKL_EQ(i, hypotl, -b, -a, c); 610 } 611 } 612 613 for (i = 0; i < __arraycount(exact_cases); i++) { 614 int s; 615 616 for (s = LDBL_MIN_EXP; 617 s < LDBL_MAX_EXP - LDBL_MANT_DIG; 618 s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) { 619 volatile long double a = ldexpl(exact_cases[i].a, s); 620 volatile long double b = ldexpl(exact_cases[i].b, s); 621 long double c = ldexpl(exact_cases[i].c, s); 622 623 CHECKL_EQ(i, hypotl, a, b, c); 624 CHECKL_EQ(i, hypotl, b, a, c); 625 CHECKL_EQ(i, hypotl, a, -b, c); 626 CHECKL_EQ(i, hypotl, b, -a, c); 627 CHECKL_EQ(i, hypotl, -a, b, c); 628 CHECKL_EQ(i, hypotl, -b, a, c); 629 CHECKL_EQ(i, hypotl, -a, -b, c); 630 CHECKL_EQ(i, hypotl, -b, -a, c); 631 } 632 } 633 634#if LDBL_MANT_DIG >= 64 635 for (i = 0; i < __arraycount(exact_casesl); i++) { 636 int s; 637 638 for (s = LDBL_MIN_EXP; 639 s < LDBL_MAX_EXP - LDBL_MANT_DIG; 640 s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) { 641 volatile long double a = ldexpl(exact_casesl[i].a, s); 642 volatile long double b = ldexpl(exact_casesl[i].b, s); 643 long double c = ldexpl(exact_casesl[i].c, s); 644 645 CHECKL_EQ(i, hypotl, a, b, c); 646 CHECKL_EQ(i, hypotl, b, a, c); 647 CHECKL_EQ(i, hypotl, a, -b, c); 648 CHECKL_EQ(i, hypotl, b, -a, c); 649 CHECKL_EQ(i, hypotl, -a, b, c); 650 CHECKL_EQ(i, hypotl, -b, a, c); 651 CHECKL_EQ(i, hypotl, -a, -b, c); 652 CHECKL_EQ(i, hypotl, -b, -a, c); 653 } 654 } 655#endif 656} 657 658ATF_TC(hypot_nan); 659ATF_TC_HEAD(hypot_nan, tc) 660{ 661 atf_tc_set_md_var(tc, "descr", "hypot/hypotf/hypotl(NAN, NAN)"); 662} 663ATF_TC_BODY(hypot_nan, tc) 664{ 665#ifdef NAN 666 CHECK_NAN(0, hypot, NAN, NAN); 667 CHECK_NAN(1, hypotf, NAN, NAN); 668 CHECKL_NAN(2, hypotl, NAN, NAN); 669#else 670 atf_tc_skip("no NaNs on this architecture"); 671#endif 672} 673 674ATF_TC(pr50698); 675ATF_TC_HEAD(pr50698, tc) 676{ 677 atf_tc_set_md_var(tc, "descr", "Check for the bug of PR lib/50698"); 678} 679 680ATF_TC_BODY(pr50698, tc) 681{ 682 volatile float a = 1e-18f; 683 float val = hypotf(a, a); 684 ATF_CHECK(!isinf(val)); 685 ATF_CHECK(!isnan(val)); 686} 687 688ATF_TP_ADD_TCS(tp) 689{ 690 691 ATF_TP_ADD_TC(tp, hypot_exact); 692 ATF_TP_ADD_TC(tp, hypot_nan); 693 ATF_TP_ADD_TC(tp, hypot_trivial); 694 ATF_TP_ADD_TC(tp, hypotf_exact); 695 ATF_TP_ADD_TC(tp, hypotf_trivial); 696 ATF_TP_ADD_TC(tp, hypotl_exact); 697 ATF_TP_ADD_TC(tp, hypotl_trivial); 698 ATF_TP_ADD_TC(tp, pr50698); 699 700 return atf_no_error(); 701} 702