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