t_hypot.c revision 1.4 1 1.4 riastrad /* $NetBSD: t_hypot.c,v 1.4 2024/05/11 20:09:13 riastradh Exp $ */
2 1.1 gson
3 1.1 gson /*-
4 1.1 gson * Copyright (c) 2016 The NetBSD Foundation, Inc.
5 1.1 gson * All rights reserved.
6 1.1 gson *
7 1.1 gson * Redistribution and use in source and binary forms, with or without
8 1.1 gson * modification, are permitted provided that the following conditions
9 1.1 gson * are met:
10 1.1 gson * 1. Redistributions of source code must retain the above copyright
11 1.1 gson * notice, this list of conditions and the following disclaimer.
12 1.1 gson * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 gson * notice, this list of conditions and the following disclaimer in the
14 1.1 gson * documentation and/or other materials provided with the distribution.
15 1.1 gson *
16 1.1 gson * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 gson * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 gson * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 gson * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 gson * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 gson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 gson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 gson * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 gson * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 gson * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 gson * POSSIBILITY OF SUCH DAMAGE.
27 1.1 gson */
28 1.1 gson
29 1.1 gson #include <atf-c.h>
30 1.3 riastrad #include <float.h>
31 1.1 gson #include <math.h>
32 1.1 gson
33 1.3 riastrad #define CHECK_EQ(i, hypot, a, b, c) \
34 1.3 riastrad ATF_CHECK_MSG(hypot(a, b) == (c), \
35 1.3 riastrad "[%u] %s(%a, %a)=%a, expected %a", \
36 1.3 riastrad (i), #hypot, (a), (b), hypot(a, b), (c))
37 1.3 riastrad
38 1.3 riastrad #define CHECKL_EQ(i, hypot, a, b, c) \
39 1.3 riastrad ATF_CHECK_MSG(hypot(a, b) == (c), \
40 1.3 riastrad "[%u] %s(%La, %La)=%La, expected %La", \
41 1.3 riastrad (i), #hypot, (a), (b), hypot(a, b), (c))
42 1.3 riastrad
43 1.3 riastrad static const float trivial_casesf[] = {
44 1.3 riastrad 0,
45 1.3 riastrad #ifdef __FLT_HAS_DENORM__
46 1.3 riastrad __FLT_DENORM_MIN__,
47 1.3 riastrad 2*__FLT_DENORM_MIN__,
48 1.3 riastrad 3*__FLT_DENORM_MIN__,
49 1.3 riastrad FLT_MIN - 3*__FLT_DENORM_MIN__,
50 1.3 riastrad FLT_MIN - 2*__FLT_DENORM_MIN__,
51 1.3 riastrad FLT_MIN - __FLT_DENORM_MIN__,
52 1.3 riastrad #endif
53 1.3 riastrad FLT_MIN,
54 1.3 riastrad FLT_MIN*(1 + FLT_EPSILON),
55 1.3 riastrad FLT_MIN*(1 + 2*FLT_EPSILON),
56 1.3 riastrad 2*FLT_MIN,
57 1.3 riastrad FLT_EPSILON/2,
58 1.3 riastrad FLT_EPSILON,
59 1.3 riastrad 2*FLT_EPSILON,
60 1.3 riastrad 1 - 3*FLT_EPSILON/2,
61 1.3 riastrad 1 - 2*FLT_EPSILON/2,
62 1.3 riastrad 1 - FLT_EPSILON/2,
63 1.3 riastrad 1,
64 1.3 riastrad 1 + FLT_EPSILON,
65 1.3 riastrad 1 + 2*FLT_EPSILON,
66 1.3 riastrad 1 + 3*FLT_EPSILON,
67 1.3 riastrad 1.5 - 3*FLT_EPSILON,
68 1.3 riastrad 1.5 - 2*FLT_EPSILON,
69 1.3 riastrad 1.5 - FLT_EPSILON,
70 1.3 riastrad 1.5,
71 1.3 riastrad 1.5 + FLT_EPSILON,
72 1.3 riastrad 1.5 + 2*FLT_EPSILON,
73 1.3 riastrad 1.5 + 3*FLT_EPSILON,
74 1.3 riastrad 2,
75 1.3 riastrad 0.5/FLT_EPSILON - 0.5,
76 1.3 riastrad 0.5/FLT_EPSILON,
77 1.3 riastrad 0.5/FLT_EPSILON + 0.5,
78 1.3 riastrad 1/FLT_EPSILON,
79 1.3 riastrad FLT_MAX,
80 1.3 riastrad INFINITY,
81 1.3 riastrad };
82 1.3 riastrad
83 1.3 riastrad static const double trivial_cases[] = {
84 1.3 riastrad 0,
85 1.3 riastrad #ifdef __DBL_HAS_DENORM__
86 1.3 riastrad __DBL_DENORM_MIN__,
87 1.3 riastrad 2*__DBL_DENORM_MIN__,
88 1.3 riastrad 3*__DBL_DENORM_MIN__,
89 1.3 riastrad DBL_MIN - 3*__DBL_DENORM_MIN__,
90 1.3 riastrad DBL_MIN - 2*__DBL_DENORM_MIN__,
91 1.3 riastrad DBL_MIN - __DBL_DENORM_MIN__,
92 1.3 riastrad #endif
93 1.3 riastrad DBL_MIN,
94 1.3 riastrad DBL_MIN*(1 + DBL_EPSILON),
95 1.3 riastrad DBL_MIN*(1 + 2*DBL_EPSILON),
96 1.3 riastrad 2*DBL_MIN,
97 1.3 riastrad DBL_EPSILON/2,
98 1.3 riastrad DBL_EPSILON,
99 1.3 riastrad 2*DBL_EPSILON,
100 1.3 riastrad 1 - 3*DBL_EPSILON/2,
101 1.3 riastrad 1 - 2*DBL_EPSILON/2,
102 1.3 riastrad 1 - DBL_EPSILON/2,
103 1.3 riastrad 1,
104 1.3 riastrad 1 + DBL_EPSILON,
105 1.3 riastrad 1 + 2*DBL_EPSILON,
106 1.3 riastrad 1 + 3*DBL_EPSILON,
107 1.3 riastrad 1.5 - 3*DBL_EPSILON,
108 1.3 riastrad 1.5 - 2*DBL_EPSILON,
109 1.3 riastrad 1.5 - DBL_EPSILON,
110 1.3 riastrad 1.5,
111 1.3 riastrad 1.5 + DBL_EPSILON,
112 1.3 riastrad 1.5 + 2*DBL_EPSILON,
113 1.3 riastrad 1.5 + 3*DBL_EPSILON,
114 1.3 riastrad 2,
115 1.3 riastrad 1/FLT_EPSILON - 0.5,
116 1.3 riastrad 1/FLT_EPSILON,
117 1.3 riastrad 1/FLT_EPSILON + 0.5,
118 1.3 riastrad 0.5/DBL_EPSILON - 0.5,
119 1.3 riastrad 0.5/DBL_EPSILON,
120 1.3 riastrad 0.5/DBL_EPSILON + 0.5,
121 1.3 riastrad 1/DBL_EPSILON,
122 1.3 riastrad DBL_MAX,
123 1.3 riastrad INFINITY,
124 1.3 riastrad };
125 1.3 riastrad
126 1.3 riastrad static const long double trivial_casesl[] = {
127 1.3 riastrad 0,
128 1.3 riastrad #ifdef __LDBL_HAS_DENORM__
129 1.3 riastrad __LDBL_DENORM_MIN__,
130 1.3 riastrad 2*__LDBL_DENORM_MIN__,
131 1.3 riastrad 3*__LDBL_DENORM_MIN__,
132 1.3 riastrad LDBL_MIN - 3*__LDBL_DENORM_MIN__,
133 1.3 riastrad LDBL_MIN - 2*__LDBL_DENORM_MIN__,
134 1.3 riastrad LDBL_MIN - __LDBL_DENORM_MIN__,
135 1.3 riastrad #endif
136 1.3 riastrad LDBL_MIN,
137 1.3 riastrad LDBL_MIN*(1 + LDBL_EPSILON),
138 1.3 riastrad LDBL_MIN*(1 + 2*LDBL_EPSILON),
139 1.3 riastrad 2*LDBL_MIN,
140 1.3 riastrad LDBL_EPSILON/2,
141 1.3 riastrad LDBL_EPSILON,
142 1.3 riastrad 2*LDBL_EPSILON,
143 1.3 riastrad 1 - 3*LDBL_EPSILON/2,
144 1.3 riastrad 1 - 2*LDBL_EPSILON/2,
145 1.3 riastrad 1 - LDBL_EPSILON/2,
146 1.3 riastrad 1,
147 1.3 riastrad 1 + LDBL_EPSILON,
148 1.3 riastrad 1 + 2*LDBL_EPSILON,
149 1.3 riastrad 1 + 3*LDBL_EPSILON,
150 1.3 riastrad 1.5 - 3*LDBL_EPSILON,
151 1.3 riastrad 1.5 - 2*LDBL_EPSILON,
152 1.3 riastrad 1.5 - LDBL_EPSILON,
153 1.3 riastrad 1.5,
154 1.3 riastrad 1.5 + LDBL_EPSILON,
155 1.3 riastrad 1.5 + 2*LDBL_EPSILON,
156 1.3 riastrad 1.5 + 3*LDBL_EPSILON,
157 1.3 riastrad 2,
158 1.3 riastrad 1/FLT_EPSILON - 0.5,
159 1.3 riastrad 1/FLT_EPSILON,
160 1.3 riastrad 1/FLT_EPSILON + 0.5,
161 1.3 riastrad #ifdef __HAVE_LONG_DOUBLE
162 1.3 riastrad 1/DBL_EPSILON - 0.5L,
163 1.3 riastrad 1/DBL_EPSILON,
164 1.3 riastrad 1/DBL_EPSILON + 0.5L,
165 1.3 riastrad #endif
166 1.3 riastrad 0.5/LDBL_EPSILON - 0.5,
167 1.3 riastrad 0.5/LDBL_EPSILON,
168 1.3 riastrad 0.5/LDBL_EPSILON + 0.5,
169 1.3 riastrad 1/LDBL_EPSILON,
170 1.3 riastrad LDBL_MAX,
171 1.3 riastrad INFINITY,
172 1.3 riastrad };
173 1.3 riastrad
174 1.3 riastrad ATF_TC(hypotf_trivial);
175 1.3 riastrad ATF_TC_HEAD(hypotf_trivial, tc)
176 1.3 riastrad {
177 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotf(x,0) and hypotf(0,x)");
178 1.3 riastrad }
179 1.3 riastrad ATF_TC_BODY(hypotf_trivial, tc)
180 1.3 riastrad {
181 1.3 riastrad unsigned i;
182 1.3 riastrad
183 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesf); i++) {
184 1.4 riastrad volatile float x = trivial_casesf[i];
185 1.3 riastrad
186 1.4 riastrad CHECK_EQ(i, hypotf, x, +0., x);
187 1.4 riastrad CHECK_EQ(i, hypotf, x, -0., x);
188 1.4 riastrad CHECK_EQ(i, hypotf, +0., x, x);
189 1.4 riastrad CHECK_EQ(i, hypotf, -0., x, x);
190 1.4 riastrad CHECK_EQ(i, hypotf, -x, +0., x);
191 1.4 riastrad CHECK_EQ(i, hypotf, -x, -0., x);
192 1.4 riastrad CHECK_EQ(i, hypotf, +0., -x, x);
193 1.4 riastrad CHECK_EQ(i, hypotf, -0., -x, x);
194 1.3 riastrad }
195 1.3 riastrad }
196 1.3 riastrad
197 1.3 riastrad ATF_TC(hypot_trivial);
198 1.3 riastrad ATF_TC_HEAD(hypot_trivial, tc)
199 1.3 riastrad {
200 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypot(x,0) and hypot(0,x)");
201 1.3 riastrad }
202 1.3 riastrad ATF_TC_BODY(hypot_trivial, tc)
203 1.3 riastrad {
204 1.3 riastrad unsigned i;
205 1.3 riastrad
206 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesf); i++) {
207 1.4 riastrad volatile double x = trivial_casesf[i];
208 1.3 riastrad
209 1.4 riastrad CHECK_EQ(i, hypot, x, +0., x);
210 1.4 riastrad CHECK_EQ(i, hypot, x, -0., x);
211 1.4 riastrad CHECK_EQ(i, hypot, +0., x, x);
212 1.4 riastrad CHECK_EQ(i, hypot, -0., x, x);
213 1.4 riastrad CHECK_EQ(i, hypot, -x, +0., x);
214 1.4 riastrad CHECK_EQ(i, hypot, -x, -0., x);
215 1.4 riastrad CHECK_EQ(i, hypot, +0., -x, x);
216 1.4 riastrad CHECK_EQ(i, hypot, -0., -x, x);
217 1.3 riastrad }
218 1.3 riastrad
219 1.3 riastrad for (i = 0; i < __arraycount(trivial_cases); i++) {
220 1.4 riastrad volatile double x = trivial_cases[i];
221 1.3 riastrad
222 1.4 riastrad CHECK_EQ(i, hypot, x, +0., x);
223 1.4 riastrad CHECK_EQ(i, hypot, x, -0., x);
224 1.4 riastrad CHECK_EQ(i, hypot, +0., x, x);
225 1.4 riastrad CHECK_EQ(i, hypot, -0., x, x);
226 1.4 riastrad CHECK_EQ(i, hypot, -x, +0., x);
227 1.4 riastrad CHECK_EQ(i, hypot, -x, -0., x);
228 1.4 riastrad CHECK_EQ(i, hypot, +0., -x, x);
229 1.4 riastrad CHECK_EQ(i, hypot, -0., -x, x);
230 1.3 riastrad }
231 1.3 riastrad }
232 1.3 riastrad
233 1.3 riastrad ATF_TC(hypotl_trivial);
234 1.3 riastrad ATF_TC_HEAD(hypotl_trivial, tc)
235 1.3 riastrad {
236 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotl(x,0) and hypotl(0,x)");
237 1.3 riastrad }
238 1.3 riastrad ATF_TC_BODY(hypotl_trivial, tc)
239 1.1 gson {
240 1.3 riastrad unsigned i;
241 1.3 riastrad
242 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesf); i++) {
243 1.4 riastrad volatile long double x = trivial_casesf[i];
244 1.3 riastrad
245 1.4 riastrad CHECKL_EQ(i, hypotl, x, +0.L, x);
246 1.4 riastrad CHECKL_EQ(i, hypotl, x, -0.L, x);
247 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, x, x);
248 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, x, x);
249 1.4 riastrad CHECKL_EQ(i, hypotl, -x, +0.L, x);
250 1.4 riastrad CHECKL_EQ(i, hypotl, -x, -0.L, x);
251 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, -x, x);
252 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, -x, x);
253 1.3 riastrad }
254 1.3 riastrad
255 1.3 riastrad for (i = 0; i < __arraycount(trivial_cases); i++) {
256 1.4 riastrad volatile long double x = trivial_cases[i];
257 1.3 riastrad
258 1.4 riastrad CHECKL_EQ(i, hypotl, x, +0.L, x);
259 1.4 riastrad CHECKL_EQ(i, hypotl, x, -0.L, x);
260 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, x, x);
261 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, x, x);
262 1.4 riastrad CHECKL_EQ(i, hypotl, -x, +0.L, x);
263 1.4 riastrad CHECKL_EQ(i, hypotl, -x, -0.L, x);
264 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, -x, x);
265 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, -x, x);
266 1.3 riastrad }
267 1.3 riastrad
268 1.3 riastrad #if __HAVE_LONG_DOUBLE + 0 == 128
269 1.3 riastrad atf_tc_expect_fail("PR lib/58245: hypotl is broken on ld128 ports");
270 1.3 riastrad #endif
271 1.3 riastrad
272 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesl); i++) {
273 1.4 riastrad volatile long double x = trivial_casesl[i];
274 1.3 riastrad
275 1.4 riastrad CHECKL_EQ(i, hypotl, x, +0.L, x);
276 1.4 riastrad CHECKL_EQ(i, hypotl, x, -0.L, x);
277 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, x, x);
278 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, x, x);
279 1.4 riastrad CHECKL_EQ(i, hypotl, -x, +0.L, x);
280 1.4 riastrad CHECKL_EQ(i, hypotl, -x, -0.L, x);
281 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, -x, x);
282 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, -x, x);
283 1.3 riastrad }
284 1.1 gson }
285 1.1 gson
286 1.3 riastrad __CTASSERT(FLT_MANT_DIG >= 24);
287 1.3 riastrad static const struct {
288 1.3 riastrad float a, b, c;
289 1.3 riastrad } exact_casesf[] = {
290 1.3 riastrad { 3, 4, 5 },
291 1.3 riastrad { 5, 12, 13 },
292 1.3 riastrad { 9, 12, 15 },
293 1.3 riastrad { 0x1001, 0x801000, 0x801001 },
294 1.3 riastrad { 4248257, 1130976, 4396225 },
295 1.3 riastrad };
296 1.3 riastrad
297 1.3 riastrad __CTASSERT(DBL_MANT_DIG >= 53);
298 1.3 riastrad static const struct {
299 1.3 riastrad double a, b, c;
300 1.3 riastrad } exact_cases[] = {
301 1.3 riastrad { 3378249543467007, 4505248894795776, 5631148868747265 },
302 1.3 riastrad { 0x7ffffff, 0x1ffffff8000000, 0x1ffffff8000001 },
303 1.3 riastrad #if DBL_MANT_DIG >= 56
304 1.3 riastrad { 13514123525517439, 18018830919909120, 22523538851237761 },
305 1.3 riastrad { 0x1fffffff, 0x1ffffffe0000000, 0x1ffffffe0000001 },
306 1.3 riastrad #endif
307 1.3 riastrad };
308 1.3 riastrad
309 1.3 riastrad #if LDBL_MANT_DIG >= 64
310 1.3 riastrad static const struct {
311 1.3 riastrad long double a, b, c;
312 1.3 riastrad } exact_casesl[] = {
313 1.3 riastrad { 3458976450080784639, 4611968592949214720, 5764960744407842561 },
314 1.3 riastrad { 0x1ffffffff, 0x1fffffffe00000000p0L, 0x1fffffffe00000001p0L },
315 1.3 riastrad #if LDBL_MANT_DIG >= 113
316 1.3 riastrad { 973555668229277869436257492279295.L,
317 1.3 riastrad 1298074224305703705819019479072768.L,
318 1.3 riastrad 1622592780382129686316970078625793.L },
319 1.3 riastrad { 0x1ffffffffffffff,
320 1.3 riastrad 0x1fffffffffffffe00000000000000p0L,
321 1.3 riastrad 0x1fffffffffffffe00000000000001p0L },
322 1.3 riastrad #endif
323 1.3 riastrad };
324 1.3 riastrad #endif
325 1.3 riastrad
326 1.3 riastrad ATF_TC(hypotf_exact);
327 1.3 riastrad ATF_TC_HEAD(hypotf_exact, tc)
328 1.1 gson {
329 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotf on scaled Pythagorean triples");
330 1.3 riastrad }
331 1.3 riastrad ATF_TC_BODY(hypotf_exact, tc)
332 1.3 riastrad {
333 1.3 riastrad unsigned i;
334 1.3 riastrad
335 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
336 1.3 riastrad int s;
337 1.3 riastrad
338 1.3 riastrad for (s = FLT_MIN_EXP;
339 1.3 riastrad s < FLT_MAX_EXP - FLT_MANT_DIG;
340 1.3 riastrad s += (FLT_MAX_EXP - FLT_MANT_DIG - FLT_MIN_EXP)/5) {
341 1.3 riastrad volatile double a = ldexpf(exact_casesf[i].a, s);
342 1.3 riastrad volatile double b = ldexpf(exact_casesf[i].b, s);
343 1.3 riastrad float c = ldexpf(exact_casesf[i].c, s);
344 1.3 riastrad
345 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
346 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
347 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
348 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
349 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
350 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
351 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
352 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
353 1.3 riastrad }
354 1.3 riastrad }
355 1.1 gson }
356 1.1 gson
357 1.3 riastrad ATF_TC(hypot_exact);
358 1.3 riastrad ATF_TC_HEAD(hypot_exact, tc)
359 1.1 gson {
360 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypot on scaled Pythagorean triples");
361 1.3 riastrad }
362 1.3 riastrad ATF_TC_BODY(hypot_exact, tc)
363 1.3 riastrad {
364 1.3 riastrad unsigned i;
365 1.3 riastrad
366 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
367 1.3 riastrad int s;
368 1.3 riastrad
369 1.3 riastrad for (s = DBL_MIN_EXP;
370 1.3 riastrad s < DBL_MAX_EXP - DBL_MANT_DIG;
371 1.3 riastrad s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) {
372 1.3 riastrad volatile double a = ldexp(exact_casesf[i].a, s);
373 1.3 riastrad volatile double b = ldexp(exact_casesf[i].b, s);
374 1.3 riastrad double c = ldexp(exact_casesf[i].c, s);
375 1.3 riastrad
376 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
377 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
378 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
379 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
380 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
381 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
382 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
383 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
384 1.3 riastrad }
385 1.3 riastrad }
386 1.3 riastrad
387 1.3 riastrad for (i = 0; i < __arraycount(exact_cases); i++) {
388 1.3 riastrad int s;
389 1.3 riastrad
390 1.3 riastrad for (s = DBL_MIN_EXP;
391 1.3 riastrad s < DBL_MAX_EXP - DBL_MANT_DIG;
392 1.3 riastrad s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) {
393 1.3 riastrad volatile double a = ldexp(exact_cases[i].a, s);
394 1.3 riastrad volatile double b = ldexp(exact_cases[i].b, s);
395 1.3 riastrad double c = ldexp(exact_cases[i].c, s);
396 1.3 riastrad
397 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
398 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
399 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
400 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
401 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
402 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
403 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
404 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
405 1.3 riastrad }
406 1.3 riastrad }
407 1.1 gson }
408 1.1 gson
409 1.3 riastrad ATF_TC(hypotl_exact);
410 1.3 riastrad ATF_TC_HEAD(hypotl_exact, tc)
411 1.1 gson {
412 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotl on scaled Pythagorean triples");
413 1.3 riastrad }
414 1.3 riastrad ATF_TC_BODY(hypotl_exact, tc)
415 1.3 riastrad {
416 1.3 riastrad unsigned i;
417 1.3 riastrad
418 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
419 1.3 riastrad int s;
420 1.3 riastrad
421 1.3 riastrad for (s = LDBL_MIN_EXP;
422 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
423 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
424 1.3 riastrad volatile long double a = ldexpl(exact_casesf[i].a, s);
425 1.3 riastrad volatile long double b = ldexpl(exact_casesf[i].b, s);
426 1.3 riastrad long double c = ldexpl(exact_casesf[i].c, s);
427 1.3 riastrad
428 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
429 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
430 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c);
431 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c);
432 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c);
433 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c);
434 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c);
435 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c);
436 1.3 riastrad }
437 1.3 riastrad }
438 1.3 riastrad
439 1.3 riastrad for (i = 0; i < __arraycount(exact_cases); i++) {
440 1.3 riastrad int s;
441 1.3 riastrad
442 1.3 riastrad for (s = LDBL_MIN_EXP;
443 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
444 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
445 1.3 riastrad volatile long double a = ldexpl(exact_cases[i].a, s);
446 1.3 riastrad volatile long double b = ldexpl(exact_cases[i].b, s);
447 1.3 riastrad long double c = ldexpl(exact_cases[i].c, s);
448 1.3 riastrad
449 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
450 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
451 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c);
452 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c);
453 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c);
454 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c);
455 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c);
456 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c);
457 1.3 riastrad }
458 1.3 riastrad }
459 1.3 riastrad
460 1.3 riastrad #if __HAVE_LONG_DOUBLE + 0 == 128
461 1.3 riastrad atf_tc_expect_fail("PR lib/58245: hypotl is broken on ld128 ports");
462 1.3 riastrad #endif
463 1.3 riastrad
464 1.3 riastrad #if LDBL_MANT_DIG >= 64
465 1.3 riastrad for (i = 0; i < __arraycount(exact_casesl); i++) {
466 1.3 riastrad int s;
467 1.3 riastrad
468 1.3 riastrad for (s = LDBL_MIN_EXP;
469 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
470 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
471 1.3 riastrad volatile long double a = ldexpl(exact_casesl[i].a, s);
472 1.3 riastrad volatile long double b = ldexpl(exact_casesl[i].b, s);
473 1.3 riastrad long double c = ldexpl(exact_casesl[i].c, s);
474 1.3 riastrad
475 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
476 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
477 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c);
478 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c);
479 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c);
480 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c);
481 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c);
482 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c);
483 1.3 riastrad }
484 1.3 riastrad }
485 1.3 riastrad #endif
486 1.1 gson }
487 1.1 gson
488 1.1 gson ATF_TC(pr50698);
489 1.1 gson ATF_TC_HEAD(pr50698, tc)
490 1.1 gson {
491 1.2 jruoho atf_tc_set_md_var(tc, "descr", "Check for the bug of PR lib/50698");
492 1.1 gson }
493 1.1 gson
494 1.1 gson ATF_TC_BODY(pr50698, tc)
495 1.1 gson {
496 1.1 gson volatile float a = 1e-18f;
497 1.1 gson float val = hypotf(a, a);
498 1.1 gson ATF_CHECK(!isinf(val));
499 1.1 gson ATF_CHECK(!isnan(val));
500 1.1 gson }
501 1.1 gson
502 1.1 gson ATF_TP_ADD_TCS(tp)
503 1.1 gson {
504 1.1 gson
505 1.3 riastrad ATF_TP_ADD_TC(tp, hypot_exact);
506 1.3 riastrad ATF_TP_ADD_TC(tp, hypot_trivial);
507 1.3 riastrad ATF_TP_ADD_TC(tp, hypotf_exact);
508 1.3 riastrad ATF_TP_ADD_TC(tp, hypotf_trivial);
509 1.3 riastrad ATF_TP_ADD_TC(tp, hypotl_exact);
510 1.3 riastrad ATF_TP_ADD_TC(tp, hypotl_trivial);
511 1.1 gson ATF_TP_ADD_TC(tp, pr50698);
512 1.1 gson
513 1.1 gson return atf_no_error();
514 1.1 gson }
515