Home | History | Annotate | Line # | Download | only in libm
      1 /* $NetBSD: t_hypot.c,v 1.9 2025/04/07 01:31:18 riastradh 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 
     54 static const float trivial_casesf[] = {
     55 	0,
     56 #if __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 
     94 static const double trivial_cases[] = {
     95 	0,
     96 #if __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 
    137 static const long double trivial_casesl[] = {
    138 	0,
    139 #if __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 
    185 ATF_TC(hypotf_trivial);
    186 ATF_TC_HEAD(hypotf_trivial, tc)
    187 {
    188 	atf_tc_set_md_var(tc, "descr", "hypotf(x,0) and hypotf(0,x)");
    189 }
    190 ATF_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 
    233 ATF_TC(hypot_trivial);
    234 ATF_TC_HEAD(hypot_trivial, tc)
    235 {
    236 	atf_tc_set_md_var(tc, "descr", "hypot(x,0) and hypot(0,x)");
    237 }
    238 ATF_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 
    319 ATF_TC(hypotl_trivial);
    320 ATF_TC_HEAD(hypotl_trivial, tc)
    321 {
    322 	atf_tc_set_md_var(tc, "descr", "hypotl(x,0) and hypotl(0,x)");
    323 }
    324 ATF_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);
    461 static 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);
    472 static 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
    484 static 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 
    500 ATF_TC(hypotf_exact);
    501 ATF_TC_HEAD(hypotf_exact, tc)
    502 {
    503 	atf_tc_set_md_var(tc, "descr", "hypotf on scaled Pythagorean triples");
    504 }
    505 ATF_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 
    531 ATF_TC(hypot_exact);
    532 ATF_TC_HEAD(hypot_exact, tc)
    533 {
    534 	atf_tc_set_md_var(tc, "descr", "hypot on scaled Pythagorean triples");
    535 }
    536 ATF_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 
    583 ATF_TC(hypotl_exact);
    584 ATF_TC_HEAD(hypotl_exact, tc)
    585 {
    586 	atf_tc_set_md_var(tc, "descr", "hypotl on scaled Pythagorean triples");
    587 }
    588 ATF_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 
    658 ATF_TC(hypot_nan);
    659 ATF_TC_HEAD(hypot_nan, tc)
    660 {
    661 	atf_tc_set_md_var(tc, "descr", "hypot/hypotf/hypotl(NAN, NAN)");
    662 }
    663 ATF_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 
    674 ATF_TC(pr50698);
    675 ATF_TC_HEAD(pr50698, tc)
    676 {
    677 	atf_tc_set_md_var(tc, "descr", "Check for the bug of PR lib/50698");
    678 }
    679 
    680 ATF_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 
    688 ATF_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