xref: /netbsd-src/tests/lib/libm/t_hypot.c (revision 7e2cd5d094cc1755df05b9cf1ae8b3b65024995b)
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 
54 static 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 
94 static 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 
137 static 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 
185 ATF_TC(hypotf_trivial);
ATF_TC_HEAD(hypotf_trivial,tc)186 ATF_TC_HEAD(hypotf_trivial, tc)
187 {
188 	atf_tc_set_md_var(tc, "descr", "hypotf(x,0) and hypotf(0,x)");
189 }
ATF_TC_BODY(hypotf_trivial,tc)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);
ATF_TC_HEAD(hypot_trivial,tc)234 ATF_TC_HEAD(hypot_trivial, tc)
235 {
236 	atf_tc_set_md_var(tc, "descr", "hypot(x,0) and hypot(0,x)");
237 }
ATF_TC_BODY(hypot_trivial,tc)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);
ATF_TC_HEAD(hypotl_trivial,tc)320 ATF_TC_HEAD(hypotl_trivial, tc)
321 {
322 	atf_tc_set_md_var(tc, "descr", "hypotl(x,0) and hypotl(0,x)");
323 }
ATF_TC_BODY(hypotl_trivial,tc)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);
ATF_TC_HEAD(hypotf_exact,tc)501 ATF_TC_HEAD(hypotf_exact, tc)
502 {
503 	atf_tc_set_md_var(tc, "descr", "hypotf on scaled Pythagorean triples");
504 }
ATF_TC_BODY(hypotf_exact,tc)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);
ATF_TC_HEAD(hypot_exact,tc)532 ATF_TC_HEAD(hypot_exact, tc)
533 {
534 	atf_tc_set_md_var(tc, "descr", "hypot on scaled Pythagorean triples");
535 }
ATF_TC_BODY(hypot_exact,tc)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);
ATF_TC_HEAD(hypotl_exact,tc)584 ATF_TC_HEAD(hypotl_exact, tc)
585 {
586 	atf_tc_set_md_var(tc, "descr", "hypotl on scaled Pythagorean triples");
587 }
ATF_TC_BODY(hypotl_exact,tc)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);
ATF_TC_HEAD(hypot_nan,tc)659 ATF_TC_HEAD(hypot_nan, tc)
660 {
661 	atf_tc_set_md_var(tc, "descr", "hypot/hypotf/hypotl(NAN, NAN)");
662 }
ATF_TC_BODY(hypot_nan,tc)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);
ATF_TC_HEAD(pr50698,tc)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 
ATF_TC_BODY(pr50698,tc)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 
ATF_TP_ADD_TCS(tp)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