t_hypot.c revision 1.3 1 1.3 riastrad /* $NetBSD: t_hypot.c,v 1.3 2024/05/11 19:08:29 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.3 riastrad volatile float y, x = trivial_casesf[i];
185 1.3 riastrad
186 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotf(x, 0)), x,
187 1.3 riastrad "[%u] x=%g=%a hypotf(x, 0)=x=%g=%a",
188 1.3 riastrad i, x, x, y, y);
189 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotf(-x, 0)), x,
190 1.3 riastrad "[%u] x=%g=%a hypotf(-x, 0)=x=%g=%a",
191 1.3 riastrad i, x, x, y, y);
192 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotf(0, x)), x,
193 1.3 riastrad "[%u] x=%g=%a hypotf(0, x)=x=%g=%a",
194 1.3 riastrad i, x, x, y, y);
195 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotf(0, -x)), x,
196 1.3 riastrad "[%u] x=%g=%a hypotf(0, -x)=x=%g=%a",
197 1.3 riastrad i, x, x, y, y);
198 1.3 riastrad }
199 1.3 riastrad }
200 1.3 riastrad
201 1.3 riastrad ATF_TC(hypot_trivial);
202 1.3 riastrad ATF_TC_HEAD(hypot_trivial, tc)
203 1.3 riastrad {
204 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypot(x,0) and hypot(0,x)");
205 1.3 riastrad }
206 1.3 riastrad ATF_TC_BODY(hypot_trivial, tc)
207 1.3 riastrad {
208 1.3 riastrad unsigned i;
209 1.3 riastrad
210 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesf); i++) {
211 1.3 riastrad volatile double y, x = trivial_casesf[i];
212 1.3 riastrad
213 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypot(x, 0)), x,
214 1.3 riastrad "[%u] x=%g=%a hypot(x, 0)=x=%g=%a",
215 1.3 riastrad i, x, x, y, y);
216 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypot(-x, 0)), x,
217 1.3 riastrad "[%u] x=%g=%a hypot(-x, 0)=x=%g=%a",
218 1.3 riastrad i, x, x, y, y);
219 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypot(0, x)), x,
220 1.3 riastrad "[%u] x=%g=%a hypot(0, x)=x=%g=%a",
221 1.3 riastrad i, x, x, y, y);
222 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypot(0, -x)), x,
223 1.3 riastrad "[%u] x=%g=%a hypot(0, -x)=x=%g=%a",
224 1.3 riastrad i, x, x, y, y);
225 1.3 riastrad }
226 1.3 riastrad
227 1.3 riastrad for (i = 0; i < __arraycount(trivial_cases); i++) {
228 1.3 riastrad volatile double y, x = trivial_cases[i];
229 1.3 riastrad
230 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypot(x, 0)), x,
231 1.3 riastrad "[%u] x=%g=%a hypot(x, 0)=x=%g=%a",
232 1.3 riastrad i, x, x, y, y);
233 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypot(-x, 0)), x,
234 1.3 riastrad "[%u] x=%g=%a hypot(-x, 0)=x=%g=%a",
235 1.3 riastrad i, x, x, y, y);
236 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypot(0, x)), x,
237 1.3 riastrad "[%u] x=%g=%a hypot(0, x)=x=%g=%a",
238 1.3 riastrad i, x, x, y, y);
239 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypot(0, -x)), x,
240 1.3 riastrad "[%u] x=%g=%a hypot(0, -x)=x=%g=%a",
241 1.3 riastrad i, x, x, y, y);
242 1.3 riastrad }
243 1.3 riastrad }
244 1.3 riastrad
245 1.3 riastrad ATF_TC(hypotl_trivial);
246 1.3 riastrad ATF_TC_HEAD(hypotl_trivial, tc)
247 1.3 riastrad {
248 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotl(x,0) and hypotl(0,x)");
249 1.3 riastrad }
250 1.3 riastrad ATF_TC_BODY(hypotl_trivial, tc)
251 1.1 gson {
252 1.3 riastrad unsigned i;
253 1.3 riastrad
254 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesf); i++) {
255 1.3 riastrad volatile long double y, x = trivial_casesf[i];
256 1.3 riastrad
257 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(x, 0)), x,
258 1.3 riastrad "[%u] x=%Lg=%La hypotl(x, 0)=x=%Lg=%La",
259 1.3 riastrad i, x, x, y, y);
260 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(-x, 0)), x,
261 1.3 riastrad "[%u] x=%Lg=%La hypotl(-x, 0)=x=%Lg=%La",
262 1.3 riastrad i, x, x, y, y);
263 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(0, x)), x,
264 1.3 riastrad "[%u] x=%Lg=%La hypotl(0, x)=x=%Lg=%La",
265 1.3 riastrad i, x, x, y, y);
266 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(0, -x)), x,
267 1.3 riastrad "[%u] x=%Lg=%La hypotl(0, -x)=x=%Lg=%La",
268 1.3 riastrad i, x, x, y, y);
269 1.3 riastrad }
270 1.3 riastrad
271 1.3 riastrad for (i = 0; i < __arraycount(trivial_cases); i++) {
272 1.3 riastrad volatile long double y, x = trivial_cases[i];
273 1.3 riastrad
274 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(x, 0)), x,
275 1.3 riastrad "[%u] x=%Lg=%La hypotl(x, 0)=x=%Lg=%La",
276 1.3 riastrad i, x, x, y, y);
277 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(-x, 0)), x,
278 1.3 riastrad "[%u] x=%Lg=%La hypotl(-x, 0)=x=%Lg=%La",
279 1.3 riastrad i, x, x, y, y);
280 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(0, x)), x,
281 1.3 riastrad "[%u] x=%Lg=%La hypotl(0, x)=x=%Lg=%La",
282 1.3 riastrad i, x, x, y, y);
283 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(0, -x)), x,
284 1.3 riastrad "[%u] x=%Lg=%La hypotl(0, -x)=x=%Lg=%La",
285 1.3 riastrad i, x, x, y, y);
286 1.3 riastrad }
287 1.3 riastrad
288 1.3 riastrad #if __HAVE_LONG_DOUBLE + 0 == 128
289 1.3 riastrad atf_tc_expect_fail("PR lib/58245: hypotl is broken on ld128 ports");
290 1.3 riastrad #endif
291 1.3 riastrad
292 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesl); i++) {
293 1.3 riastrad volatile long double y, x = trivial_casesl[i];
294 1.3 riastrad
295 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(x, 0)), x,
296 1.3 riastrad "[%u] x=%Lg=%La hypotl(x, 0)=x=%Lg=%La",
297 1.3 riastrad i, x, x, y, y);
298 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(-x, 0)), x,
299 1.3 riastrad "[%u] x=%Lg=%La hypotl(-x, 0)=x=%Lg=%La",
300 1.3 riastrad i, x, x, y, y);
301 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(0, x)), x,
302 1.3 riastrad "[%u] x=%Lg=%La hypotl(0, x)=x=%Lg=%La",
303 1.3 riastrad i, x, x, y, y);
304 1.3 riastrad ATF_CHECK_EQ_MSG((y = hypotl(0, -x)), x,
305 1.3 riastrad "[%u] x=%Lg=%La hypotl(0, -x)=x=%Lg=%La",
306 1.3 riastrad i, x, x, y, y);
307 1.3 riastrad }
308 1.1 gson }
309 1.1 gson
310 1.3 riastrad __CTASSERT(FLT_MANT_DIG >= 24);
311 1.3 riastrad static const struct {
312 1.3 riastrad float a, b, c;
313 1.3 riastrad } exact_casesf[] = {
314 1.3 riastrad { 3, 4, 5 },
315 1.3 riastrad { 5, 12, 13 },
316 1.3 riastrad { 9, 12, 15 },
317 1.3 riastrad { 0x1001, 0x801000, 0x801001 },
318 1.3 riastrad { 4248257, 1130976, 4396225 },
319 1.3 riastrad };
320 1.3 riastrad
321 1.3 riastrad __CTASSERT(DBL_MANT_DIG >= 53);
322 1.3 riastrad static const struct {
323 1.3 riastrad double a, b, c;
324 1.3 riastrad } exact_cases[] = {
325 1.3 riastrad { 3378249543467007, 4505248894795776, 5631148868747265 },
326 1.3 riastrad { 0x7ffffff, 0x1ffffff8000000, 0x1ffffff8000001 },
327 1.3 riastrad #if DBL_MANT_DIG >= 56
328 1.3 riastrad { 13514123525517439, 18018830919909120, 22523538851237761 },
329 1.3 riastrad { 0x1fffffff, 0x1ffffffe0000000, 0x1ffffffe0000001 },
330 1.3 riastrad #endif
331 1.3 riastrad };
332 1.3 riastrad
333 1.3 riastrad #if LDBL_MANT_DIG >= 64
334 1.3 riastrad static const struct {
335 1.3 riastrad long double a, b, c;
336 1.3 riastrad } exact_casesl[] = {
337 1.3 riastrad { 3458976450080784639, 4611968592949214720, 5764960744407842561 },
338 1.3 riastrad { 0x1ffffffff, 0x1fffffffe00000000p0L, 0x1fffffffe00000001p0L },
339 1.3 riastrad #if LDBL_MANT_DIG >= 113
340 1.3 riastrad { 973555668229277869436257492279295.L,
341 1.3 riastrad 1298074224305703705819019479072768.L,
342 1.3 riastrad 1622592780382129686316970078625793.L },
343 1.3 riastrad { 0x1ffffffffffffff,
344 1.3 riastrad 0x1fffffffffffffe00000000000000p0L,
345 1.3 riastrad 0x1fffffffffffffe00000000000001p0L },
346 1.3 riastrad #endif
347 1.3 riastrad };
348 1.3 riastrad #endif
349 1.3 riastrad
350 1.3 riastrad ATF_TC(hypotf_exact);
351 1.3 riastrad ATF_TC_HEAD(hypotf_exact, tc)
352 1.1 gson {
353 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotf on scaled Pythagorean triples");
354 1.3 riastrad }
355 1.3 riastrad ATF_TC_BODY(hypotf_exact, tc)
356 1.3 riastrad {
357 1.3 riastrad unsigned i;
358 1.3 riastrad
359 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
360 1.3 riastrad int s;
361 1.3 riastrad
362 1.3 riastrad for (s = FLT_MIN_EXP;
363 1.3 riastrad s < FLT_MAX_EXP - FLT_MANT_DIG;
364 1.3 riastrad s += (FLT_MAX_EXP - FLT_MANT_DIG - FLT_MIN_EXP)/5) {
365 1.3 riastrad volatile double a = ldexpf(exact_casesf[i].a, s);
366 1.3 riastrad volatile double b = ldexpf(exact_casesf[i].b, s);
367 1.3 riastrad float c = ldexpf(exact_casesf[i].c, s);
368 1.3 riastrad
369 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
370 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
371 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
372 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
373 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
374 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
375 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
376 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
377 1.3 riastrad }
378 1.3 riastrad }
379 1.1 gson }
380 1.1 gson
381 1.3 riastrad ATF_TC(hypot_exact);
382 1.3 riastrad ATF_TC_HEAD(hypot_exact, tc)
383 1.1 gson {
384 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypot on scaled Pythagorean triples");
385 1.3 riastrad }
386 1.3 riastrad ATF_TC_BODY(hypot_exact, tc)
387 1.3 riastrad {
388 1.3 riastrad unsigned i;
389 1.3 riastrad
390 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
391 1.3 riastrad int s;
392 1.3 riastrad
393 1.3 riastrad for (s = DBL_MIN_EXP;
394 1.3 riastrad s < DBL_MAX_EXP - DBL_MANT_DIG;
395 1.3 riastrad s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) {
396 1.3 riastrad volatile double a = ldexp(exact_casesf[i].a, s);
397 1.3 riastrad volatile double b = ldexp(exact_casesf[i].b, s);
398 1.3 riastrad double c = ldexp(exact_casesf[i].c, s);
399 1.3 riastrad
400 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
401 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
402 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
403 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
404 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
405 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
406 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
407 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
408 1.3 riastrad }
409 1.3 riastrad }
410 1.3 riastrad
411 1.3 riastrad for (i = 0; i < __arraycount(exact_cases); i++) {
412 1.3 riastrad int s;
413 1.3 riastrad
414 1.3 riastrad for (s = DBL_MIN_EXP;
415 1.3 riastrad s < DBL_MAX_EXP - DBL_MANT_DIG;
416 1.3 riastrad s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) {
417 1.3 riastrad volatile double a = ldexp(exact_cases[i].a, s);
418 1.3 riastrad volatile double b = ldexp(exact_cases[i].b, s);
419 1.3 riastrad double c = ldexp(exact_cases[i].c, s);
420 1.3 riastrad
421 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
422 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
423 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
424 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
425 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
426 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
427 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
428 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
429 1.3 riastrad }
430 1.3 riastrad }
431 1.1 gson }
432 1.1 gson
433 1.3 riastrad ATF_TC(hypotl_exact);
434 1.3 riastrad ATF_TC_HEAD(hypotl_exact, tc)
435 1.1 gson {
436 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotl on scaled Pythagorean triples");
437 1.3 riastrad }
438 1.3 riastrad ATF_TC_BODY(hypotl_exact, tc)
439 1.3 riastrad {
440 1.3 riastrad unsigned i;
441 1.3 riastrad
442 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
443 1.3 riastrad int s;
444 1.3 riastrad
445 1.3 riastrad for (s = LDBL_MIN_EXP;
446 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
447 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
448 1.3 riastrad volatile long double a = ldexpl(exact_casesf[i].a, s);
449 1.3 riastrad volatile long double b = ldexpl(exact_casesf[i].b, s);
450 1.3 riastrad long double c = ldexpl(exact_casesf[i].c, s);
451 1.3 riastrad
452 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
453 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
454 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c);
455 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c);
456 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c);
457 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c);
458 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c);
459 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c);
460 1.3 riastrad }
461 1.3 riastrad }
462 1.3 riastrad
463 1.3 riastrad for (i = 0; i < __arraycount(exact_cases); i++) {
464 1.3 riastrad int s;
465 1.3 riastrad
466 1.3 riastrad for (s = LDBL_MIN_EXP;
467 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
468 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
469 1.3 riastrad volatile long double a = ldexpl(exact_cases[i].a, s);
470 1.3 riastrad volatile long double b = ldexpl(exact_cases[i].b, s);
471 1.3 riastrad long double c = ldexpl(exact_cases[i].c, s);
472 1.3 riastrad
473 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
474 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
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 }
482 1.3 riastrad }
483 1.3 riastrad
484 1.3 riastrad #if __HAVE_LONG_DOUBLE + 0 == 128
485 1.3 riastrad atf_tc_expect_fail("PR lib/58245: hypotl is broken on ld128 ports");
486 1.3 riastrad #endif
487 1.3 riastrad
488 1.3 riastrad #if LDBL_MANT_DIG >= 64
489 1.3 riastrad for (i = 0; i < __arraycount(exact_casesl); i++) {
490 1.3 riastrad int s;
491 1.3 riastrad
492 1.3 riastrad for (s = LDBL_MIN_EXP;
493 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
494 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
495 1.3 riastrad volatile long double a = ldexpl(exact_casesl[i].a, s);
496 1.3 riastrad volatile long double b = ldexpl(exact_casesl[i].b, s);
497 1.3 riastrad long double c = ldexpl(exact_casesl[i].c, s);
498 1.3 riastrad
499 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
500 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
501 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c);
502 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c);
503 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c);
504 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c);
505 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c);
506 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c);
507 1.3 riastrad }
508 1.3 riastrad }
509 1.3 riastrad #endif
510 1.1 gson }
511 1.1 gson
512 1.1 gson ATF_TC(pr50698);
513 1.1 gson ATF_TC_HEAD(pr50698, tc)
514 1.1 gson {
515 1.2 jruoho atf_tc_set_md_var(tc, "descr", "Check for the bug of PR lib/50698");
516 1.1 gson }
517 1.1 gson
518 1.1 gson ATF_TC_BODY(pr50698, tc)
519 1.1 gson {
520 1.1 gson volatile float a = 1e-18f;
521 1.1 gson float val = hypotf(a, a);
522 1.1 gson ATF_CHECK(!isinf(val));
523 1.1 gson ATF_CHECK(!isnan(val));
524 1.1 gson }
525 1.1 gson
526 1.1 gson ATF_TP_ADD_TCS(tp)
527 1.1 gson {
528 1.1 gson
529 1.3 riastrad ATF_TP_ADD_TC(tp, hypot_exact);
530 1.3 riastrad ATF_TP_ADD_TC(tp, hypot_trivial);
531 1.3 riastrad ATF_TP_ADD_TC(tp, hypotf_exact);
532 1.3 riastrad ATF_TP_ADD_TC(tp, hypotf_trivial);
533 1.3 riastrad ATF_TP_ADD_TC(tp, hypotl_exact);
534 1.3 riastrad ATF_TP_ADD_TC(tp, hypotl_trivial);
535 1.1 gson ATF_TP_ADD_TC(tp, pr50698);
536 1.1 gson
537 1.1 gson return atf_no_error();
538 1.1 gson }
539