t_hypot.c revision 1.6 1 1.6 riastrad /* $NetBSD: t_hypot.c,v 1.6 2024/05/11 20:51:41 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.6 riastrad (i), #hypot, (long double)(a), (long double)(b), hypot(a, b), \
42 1.6 riastrad (long double)(c))
43 1.6 riastrad
44 1.6 riastrad #define CHECK_NAN(i, hypot, a, b) \
45 1.6 riastrad ATF_CHECK_MSG(isnan(hypot(a, b)), \
46 1.6 riastrad "[%u] %s(%a, %a)=%a, expected NaN", \
47 1.6 riastrad (i), #hypot, (a), (b), hypot(a, b))
48 1.6 riastrad
49 1.6 riastrad #define CHECKL_NAN(i, hypot, a, b) \
50 1.6 riastrad ATF_CHECK_MSG(isnan(hypot(a, b)), \
51 1.6 riastrad "[%u] %s(%La, %La)=%La, expected NaN", \
52 1.6 riastrad (i), #hypot, (long double)(a), (long double)(b), hypot(a, b))
53 1.3 riastrad
54 1.3 riastrad static const float trivial_casesf[] = {
55 1.3 riastrad 0,
56 1.3 riastrad #ifdef __FLT_HAS_DENORM__
57 1.3 riastrad __FLT_DENORM_MIN__,
58 1.3 riastrad 2*__FLT_DENORM_MIN__,
59 1.3 riastrad 3*__FLT_DENORM_MIN__,
60 1.3 riastrad FLT_MIN - 3*__FLT_DENORM_MIN__,
61 1.3 riastrad FLT_MIN - 2*__FLT_DENORM_MIN__,
62 1.3 riastrad FLT_MIN - __FLT_DENORM_MIN__,
63 1.3 riastrad #endif
64 1.3 riastrad FLT_MIN,
65 1.3 riastrad FLT_MIN*(1 + FLT_EPSILON),
66 1.3 riastrad FLT_MIN*(1 + 2*FLT_EPSILON),
67 1.3 riastrad 2*FLT_MIN,
68 1.3 riastrad FLT_EPSILON/2,
69 1.3 riastrad FLT_EPSILON,
70 1.3 riastrad 2*FLT_EPSILON,
71 1.3 riastrad 1 - 3*FLT_EPSILON/2,
72 1.3 riastrad 1 - 2*FLT_EPSILON/2,
73 1.3 riastrad 1 - FLT_EPSILON/2,
74 1.3 riastrad 1,
75 1.3 riastrad 1 + FLT_EPSILON,
76 1.3 riastrad 1 + 2*FLT_EPSILON,
77 1.3 riastrad 1 + 3*FLT_EPSILON,
78 1.3 riastrad 1.5 - 3*FLT_EPSILON,
79 1.3 riastrad 1.5 - 2*FLT_EPSILON,
80 1.3 riastrad 1.5 - FLT_EPSILON,
81 1.3 riastrad 1.5,
82 1.3 riastrad 1.5 + FLT_EPSILON,
83 1.3 riastrad 1.5 + 2*FLT_EPSILON,
84 1.3 riastrad 1.5 + 3*FLT_EPSILON,
85 1.3 riastrad 2,
86 1.3 riastrad 0.5/FLT_EPSILON - 0.5,
87 1.3 riastrad 0.5/FLT_EPSILON,
88 1.3 riastrad 0.5/FLT_EPSILON + 0.5,
89 1.3 riastrad 1/FLT_EPSILON,
90 1.3 riastrad FLT_MAX,
91 1.3 riastrad INFINITY,
92 1.3 riastrad };
93 1.3 riastrad
94 1.3 riastrad static const double trivial_cases[] = {
95 1.3 riastrad 0,
96 1.3 riastrad #ifdef __DBL_HAS_DENORM__
97 1.3 riastrad __DBL_DENORM_MIN__,
98 1.3 riastrad 2*__DBL_DENORM_MIN__,
99 1.3 riastrad 3*__DBL_DENORM_MIN__,
100 1.3 riastrad DBL_MIN - 3*__DBL_DENORM_MIN__,
101 1.3 riastrad DBL_MIN - 2*__DBL_DENORM_MIN__,
102 1.3 riastrad DBL_MIN - __DBL_DENORM_MIN__,
103 1.3 riastrad #endif
104 1.3 riastrad DBL_MIN,
105 1.3 riastrad DBL_MIN*(1 + DBL_EPSILON),
106 1.3 riastrad DBL_MIN*(1 + 2*DBL_EPSILON),
107 1.3 riastrad 2*DBL_MIN,
108 1.3 riastrad DBL_EPSILON/2,
109 1.3 riastrad DBL_EPSILON,
110 1.3 riastrad 2*DBL_EPSILON,
111 1.3 riastrad 1 - 3*DBL_EPSILON/2,
112 1.3 riastrad 1 - 2*DBL_EPSILON/2,
113 1.3 riastrad 1 - DBL_EPSILON/2,
114 1.3 riastrad 1,
115 1.3 riastrad 1 + DBL_EPSILON,
116 1.3 riastrad 1 + 2*DBL_EPSILON,
117 1.3 riastrad 1 + 3*DBL_EPSILON,
118 1.3 riastrad 1.5 - 3*DBL_EPSILON,
119 1.3 riastrad 1.5 - 2*DBL_EPSILON,
120 1.3 riastrad 1.5 - DBL_EPSILON,
121 1.3 riastrad 1.5,
122 1.3 riastrad 1.5 + DBL_EPSILON,
123 1.3 riastrad 1.5 + 2*DBL_EPSILON,
124 1.3 riastrad 1.5 + 3*DBL_EPSILON,
125 1.3 riastrad 2,
126 1.3 riastrad 1/FLT_EPSILON - 0.5,
127 1.3 riastrad 1/FLT_EPSILON,
128 1.3 riastrad 1/FLT_EPSILON + 0.5,
129 1.3 riastrad 0.5/DBL_EPSILON - 0.5,
130 1.3 riastrad 0.5/DBL_EPSILON,
131 1.3 riastrad 0.5/DBL_EPSILON + 0.5,
132 1.3 riastrad 1/DBL_EPSILON,
133 1.3 riastrad DBL_MAX,
134 1.3 riastrad INFINITY,
135 1.3 riastrad };
136 1.3 riastrad
137 1.3 riastrad static const long double trivial_casesl[] = {
138 1.3 riastrad 0,
139 1.3 riastrad #ifdef __LDBL_HAS_DENORM__
140 1.3 riastrad __LDBL_DENORM_MIN__,
141 1.3 riastrad 2*__LDBL_DENORM_MIN__,
142 1.3 riastrad 3*__LDBL_DENORM_MIN__,
143 1.3 riastrad LDBL_MIN - 3*__LDBL_DENORM_MIN__,
144 1.3 riastrad LDBL_MIN - 2*__LDBL_DENORM_MIN__,
145 1.3 riastrad LDBL_MIN - __LDBL_DENORM_MIN__,
146 1.3 riastrad #endif
147 1.3 riastrad LDBL_MIN,
148 1.3 riastrad LDBL_MIN*(1 + LDBL_EPSILON),
149 1.3 riastrad LDBL_MIN*(1 + 2*LDBL_EPSILON),
150 1.3 riastrad 2*LDBL_MIN,
151 1.3 riastrad LDBL_EPSILON/2,
152 1.3 riastrad LDBL_EPSILON,
153 1.3 riastrad 2*LDBL_EPSILON,
154 1.3 riastrad 1 - 3*LDBL_EPSILON/2,
155 1.3 riastrad 1 - 2*LDBL_EPSILON/2,
156 1.3 riastrad 1 - LDBL_EPSILON/2,
157 1.3 riastrad 1,
158 1.3 riastrad 1 + LDBL_EPSILON,
159 1.3 riastrad 1 + 2*LDBL_EPSILON,
160 1.3 riastrad 1 + 3*LDBL_EPSILON,
161 1.3 riastrad 1.5 - 3*LDBL_EPSILON,
162 1.3 riastrad 1.5 - 2*LDBL_EPSILON,
163 1.3 riastrad 1.5 - LDBL_EPSILON,
164 1.3 riastrad 1.5,
165 1.3 riastrad 1.5 + LDBL_EPSILON,
166 1.3 riastrad 1.5 + 2*LDBL_EPSILON,
167 1.3 riastrad 1.5 + 3*LDBL_EPSILON,
168 1.3 riastrad 2,
169 1.3 riastrad 1/FLT_EPSILON - 0.5,
170 1.3 riastrad 1/FLT_EPSILON,
171 1.3 riastrad 1/FLT_EPSILON + 0.5,
172 1.3 riastrad #ifdef __HAVE_LONG_DOUBLE
173 1.3 riastrad 1/DBL_EPSILON - 0.5L,
174 1.3 riastrad 1/DBL_EPSILON,
175 1.3 riastrad 1/DBL_EPSILON + 0.5L,
176 1.3 riastrad #endif
177 1.3 riastrad 0.5/LDBL_EPSILON - 0.5,
178 1.3 riastrad 0.5/LDBL_EPSILON,
179 1.3 riastrad 0.5/LDBL_EPSILON + 0.5,
180 1.3 riastrad 1/LDBL_EPSILON,
181 1.3 riastrad LDBL_MAX,
182 1.3 riastrad INFINITY,
183 1.3 riastrad };
184 1.3 riastrad
185 1.3 riastrad ATF_TC(hypotf_trivial);
186 1.3 riastrad ATF_TC_HEAD(hypotf_trivial, tc)
187 1.3 riastrad {
188 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotf(x,0) and hypotf(0,x)");
189 1.3 riastrad }
190 1.3 riastrad ATF_TC_BODY(hypotf_trivial, tc)
191 1.3 riastrad {
192 1.3 riastrad unsigned i;
193 1.3 riastrad
194 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesf); i++) {
195 1.4 riastrad volatile float x = trivial_casesf[i];
196 1.3 riastrad
197 1.4 riastrad CHECK_EQ(i, hypotf, x, +0., x);
198 1.4 riastrad CHECK_EQ(i, hypotf, x, -0., x);
199 1.4 riastrad CHECK_EQ(i, hypotf, +0., x, x);
200 1.4 riastrad CHECK_EQ(i, hypotf, -0., x, x);
201 1.4 riastrad CHECK_EQ(i, hypotf, -x, +0., x);
202 1.4 riastrad CHECK_EQ(i, hypotf, -x, -0., x);
203 1.4 riastrad CHECK_EQ(i, hypotf, +0., -x, x);
204 1.4 riastrad CHECK_EQ(i, hypotf, -0., -x, x);
205 1.6 riastrad
206 1.6 riastrad if (isinf(INFINITY)) {
207 1.6 riastrad CHECK_EQ(i, hypotf, x, +INFINITY, INFINITY);
208 1.6 riastrad CHECK_EQ(i, hypotf, x, -INFINITY, INFINITY);
209 1.6 riastrad CHECK_EQ(i, hypotf, +INFINITY, x, INFINITY);
210 1.6 riastrad CHECK_EQ(i, hypotf, -INFINITY, x, INFINITY);
211 1.6 riastrad CHECK_EQ(i, hypotf, -x, +INFINITY, INFINITY);
212 1.6 riastrad CHECK_EQ(i, hypotf, -x, -INFINITY, INFINITY);
213 1.6 riastrad CHECK_EQ(i, hypotf, +INFINITY, -x, INFINITY);
214 1.6 riastrad CHECK_EQ(i, hypotf, -INFINITY, -x, INFINITY);
215 1.6 riastrad }
216 1.6 riastrad
217 1.6 riastrad #ifdef NAN
218 1.6 riastrad if (isinf(x)) {
219 1.6 riastrad CHECK_EQ(i, hypotf, x, NAN, INFINITY);
220 1.6 riastrad CHECK_EQ(i, hypotf, NAN, x, INFINITY);
221 1.6 riastrad CHECK_EQ(i, hypotf, -x, NAN, INFINITY);
222 1.6 riastrad CHECK_EQ(i, hypotf, NAN, -x, INFINITY);
223 1.6 riastrad } else {
224 1.6 riastrad CHECK_NAN(i, hypotf, x, NAN);
225 1.6 riastrad CHECK_NAN(i, hypotf, NAN, x);
226 1.6 riastrad CHECK_NAN(i, hypotf, -x, NAN);
227 1.6 riastrad CHECK_NAN(i, hypotf, NAN, -x);
228 1.6 riastrad }
229 1.6 riastrad #endif
230 1.3 riastrad }
231 1.3 riastrad }
232 1.3 riastrad
233 1.3 riastrad ATF_TC(hypot_trivial);
234 1.3 riastrad ATF_TC_HEAD(hypot_trivial, tc)
235 1.3 riastrad {
236 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypot(x,0) and hypot(0,x)");
237 1.3 riastrad }
238 1.3 riastrad ATF_TC_BODY(hypot_trivial, tc)
239 1.3 riastrad {
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 double x = trivial_casesf[i];
244 1.3 riastrad
245 1.4 riastrad CHECK_EQ(i, hypot, x, +0., x);
246 1.4 riastrad CHECK_EQ(i, hypot, x, -0., x);
247 1.4 riastrad CHECK_EQ(i, hypot, +0., x, x);
248 1.4 riastrad CHECK_EQ(i, hypot, -0., x, x);
249 1.4 riastrad CHECK_EQ(i, hypot, -x, +0., x);
250 1.4 riastrad CHECK_EQ(i, hypot, -x, -0., x);
251 1.4 riastrad CHECK_EQ(i, hypot, +0., -x, x);
252 1.4 riastrad CHECK_EQ(i, hypot, -0., -x, x);
253 1.6 riastrad
254 1.6 riastrad if (isinf(INFINITY)) {
255 1.6 riastrad CHECK_EQ(i, hypot, x, +INFINITY, INFINITY);
256 1.6 riastrad CHECK_EQ(i, hypot, x, -INFINITY, INFINITY);
257 1.6 riastrad CHECK_EQ(i, hypot, +INFINITY, x, INFINITY);
258 1.6 riastrad CHECK_EQ(i, hypot, -INFINITY, x, INFINITY);
259 1.6 riastrad CHECK_EQ(i, hypot, -x, +INFINITY, INFINITY);
260 1.6 riastrad CHECK_EQ(i, hypot, -x, -INFINITY, INFINITY);
261 1.6 riastrad CHECK_EQ(i, hypot, +INFINITY, -x, INFINITY);
262 1.6 riastrad CHECK_EQ(i, hypot, -INFINITY, -x, INFINITY);
263 1.6 riastrad }
264 1.6 riastrad
265 1.6 riastrad #ifdef NAN
266 1.6 riastrad if (isinf(x)) {
267 1.6 riastrad CHECK_EQ(i, hypot, x, NAN, INFINITY);
268 1.6 riastrad CHECK_EQ(i, hypot, NAN, x, INFINITY);
269 1.6 riastrad CHECK_EQ(i, hypot, -x, NAN, INFINITY);
270 1.6 riastrad CHECK_EQ(i, hypot, NAN, -x, INFINITY);
271 1.6 riastrad } else {
272 1.6 riastrad CHECK_NAN(i, hypot, x, NAN);
273 1.6 riastrad CHECK_NAN(i, hypot, NAN, x);
274 1.6 riastrad CHECK_NAN(i, hypot, -x, NAN);
275 1.6 riastrad CHECK_NAN(i, hypot, NAN, -x);
276 1.6 riastrad }
277 1.6 riastrad #endif
278 1.3 riastrad }
279 1.3 riastrad
280 1.3 riastrad for (i = 0; i < __arraycount(trivial_cases); i++) {
281 1.4 riastrad volatile double x = trivial_cases[i];
282 1.3 riastrad
283 1.4 riastrad CHECK_EQ(i, hypot, x, +0., x);
284 1.4 riastrad CHECK_EQ(i, hypot, x, -0., x);
285 1.4 riastrad CHECK_EQ(i, hypot, +0., x, x);
286 1.4 riastrad CHECK_EQ(i, hypot, -0., x, x);
287 1.4 riastrad CHECK_EQ(i, hypot, -x, +0., x);
288 1.4 riastrad CHECK_EQ(i, hypot, -x, -0., x);
289 1.4 riastrad CHECK_EQ(i, hypot, +0., -x, x);
290 1.4 riastrad CHECK_EQ(i, hypot, -0., -x, x);
291 1.6 riastrad
292 1.6 riastrad if (isinf(INFINITY)) {
293 1.6 riastrad CHECK_EQ(i, hypot, x, +INFINITY, INFINITY);
294 1.6 riastrad CHECK_EQ(i, hypot, x, -INFINITY, INFINITY);
295 1.6 riastrad CHECK_EQ(i, hypot, +INFINITY, x, INFINITY);
296 1.6 riastrad CHECK_EQ(i, hypot, -INFINITY, x, INFINITY);
297 1.6 riastrad CHECK_EQ(i, hypot, -x, +INFINITY, INFINITY);
298 1.6 riastrad CHECK_EQ(i, hypot, -x, -INFINITY, INFINITY);
299 1.6 riastrad CHECK_EQ(i, hypot, +INFINITY, -x, INFINITY);
300 1.6 riastrad CHECK_EQ(i, hypot, -INFINITY, -x, INFINITY);
301 1.6 riastrad }
302 1.6 riastrad
303 1.6 riastrad #ifdef NAN
304 1.6 riastrad if (isinf(x)) {
305 1.6 riastrad CHECK_EQ(i, hypot, x, NAN, INFINITY);
306 1.6 riastrad CHECK_EQ(i, hypot, NAN, x, INFINITY);
307 1.6 riastrad CHECK_EQ(i, hypot, -x, NAN, INFINITY);
308 1.6 riastrad CHECK_EQ(i, hypot, NAN, -x, INFINITY);
309 1.6 riastrad } else {
310 1.6 riastrad CHECK_NAN(i, hypot, x, NAN);
311 1.6 riastrad CHECK_NAN(i, hypot, NAN, x);
312 1.6 riastrad CHECK_NAN(i, hypot, -x, NAN);
313 1.6 riastrad CHECK_NAN(i, hypot, NAN, -x);
314 1.6 riastrad }
315 1.6 riastrad #endif
316 1.3 riastrad }
317 1.3 riastrad }
318 1.3 riastrad
319 1.3 riastrad ATF_TC(hypotl_trivial);
320 1.3 riastrad ATF_TC_HEAD(hypotl_trivial, tc)
321 1.3 riastrad {
322 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotl(x,0) and hypotl(0,x)");
323 1.3 riastrad }
324 1.3 riastrad ATF_TC_BODY(hypotl_trivial, tc)
325 1.1 gson {
326 1.3 riastrad unsigned i;
327 1.3 riastrad
328 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesf); i++) {
329 1.4 riastrad volatile long double x = trivial_casesf[i];
330 1.3 riastrad
331 1.4 riastrad CHECKL_EQ(i, hypotl, x, +0.L, x);
332 1.4 riastrad CHECKL_EQ(i, hypotl, x, -0.L, x);
333 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, x, x);
334 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, x, x);
335 1.4 riastrad CHECKL_EQ(i, hypotl, -x, +0.L, x);
336 1.4 riastrad CHECKL_EQ(i, hypotl, -x, -0.L, x);
337 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, -x, x);
338 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, -x, x);
339 1.6 riastrad
340 1.6 riastrad if (isinf(INFINITY)) {
341 1.6 riastrad CHECKL_EQ(i, hypotl, x, +INFINITY, INFINITY);
342 1.6 riastrad CHECKL_EQ(i, hypotl, x, -INFINITY, INFINITY);
343 1.6 riastrad CHECKL_EQ(i, hypotl, +INFINITY, x, INFINITY);
344 1.6 riastrad CHECKL_EQ(i, hypotl, -INFINITY, x, INFINITY);
345 1.6 riastrad CHECKL_EQ(i, hypotl, -x, +INFINITY, INFINITY);
346 1.6 riastrad CHECKL_EQ(i, hypotl, -x, -INFINITY, INFINITY);
347 1.6 riastrad CHECKL_EQ(i, hypotl, +INFINITY, -x, INFINITY);
348 1.6 riastrad CHECKL_EQ(i, hypotl, -INFINITY, -x, INFINITY);
349 1.6 riastrad }
350 1.6 riastrad
351 1.6 riastrad #ifdef NAN
352 1.6 riastrad if (isinf(x)) {
353 1.6 riastrad CHECKL_EQ(i, hypotl, x, NAN, INFINITY);
354 1.6 riastrad CHECKL_EQ(i, hypotl, NAN, x, INFINITY);
355 1.6 riastrad CHECKL_EQ(i, hypotl, -x, NAN, INFINITY);
356 1.6 riastrad CHECKL_EQ(i, hypotl, NAN, -x, INFINITY);
357 1.6 riastrad } else {
358 1.6 riastrad CHECKL_NAN(i, hypotl, x, NAN);
359 1.6 riastrad CHECKL_NAN(i, hypotl, NAN, x);
360 1.6 riastrad CHECKL_NAN(i, hypotl, -x, NAN);
361 1.6 riastrad CHECKL_NAN(i, hypotl, NAN, -x);
362 1.6 riastrad }
363 1.6 riastrad #endif
364 1.3 riastrad }
365 1.3 riastrad
366 1.3 riastrad for (i = 0; i < __arraycount(trivial_cases); i++) {
367 1.4 riastrad volatile long double x = trivial_cases[i];
368 1.3 riastrad
369 1.4 riastrad CHECKL_EQ(i, hypotl, x, +0.L, x);
370 1.4 riastrad CHECKL_EQ(i, hypotl, x, -0.L, x);
371 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, x, x);
372 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, x, x);
373 1.4 riastrad CHECKL_EQ(i, hypotl, -x, +0.L, x);
374 1.4 riastrad CHECKL_EQ(i, hypotl, -x, -0.L, x);
375 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, -x, x);
376 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, -x, x);
377 1.6 riastrad
378 1.6 riastrad if (isinf(INFINITY)) {
379 1.6 riastrad CHECKL_EQ(i, hypotl, x, +INFINITY, INFINITY);
380 1.6 riastrad CHECKL_EQ(i, hypotl, x, -INFINITY, INFINITY);
381 1.6 riastrad CHECKL_EQ(i, hypotl, +INFINITY, x, INFINITY);
382 1.6 riastrad CHECKL_EQ(i, hypotl, -INFINITY, x, INFINITY);
383 1.6 riastrad CHECKL_EQ(i, hypotl, -x, +INFINITY, INFINITY);
384 1.6 riastrad CHECKL_EQ(i, hypotl, -x, -INFINITY, INFINITY);
385 1.6 riastrad CHECKL_EQ(i, hypotl, +INFINITY, -x, INFINITY);
386 1.6 riastrad CHECKL_EQ(i, hypotl, -INFINITY, -x, INFINITY);
387 1.6 riastrad }
388 1.6 riastrad
389 1.6 riastrad #ifdef NAN
390 1.6 riastrad if (isinf(x)) {
391 1.6 riastrad CHECKL_EQ(i, hypotl, x, NAN, INFINITY);
392 1.6 riastrad CHECKL_EQ(i, hypotl, NAN, x, INFINITY);
393 1.6 riastrad CHECKL_EQ(i, hypotl, -x, NAN, INFINITY);
394 1.6 riastrad CHECKL_EQ(i, hypotl, NAN, -x, INFINITY);
395 1.6 riastrad } else {
396 1.6 riastrad CHECKL_NAN(i, hypotl, x, NAN);
397 1.6 riastrad CHECKL_NAN(i, hypotl, NAN, x);
398 1.6 riastrad CHECKL_NAN(i, hypotl, -x, NAN);
399 1.6 riastrad CHECKL_NAN(i, hypotl, NAN, -x);
400 1.6 riastrad }
401 1.6 riastrad #endif
402 1.3 riastrad }
403 1.3 riastrad
404 1.3 riastrad for (i = 0; i < __arraycount(trivial_casesl); i++) {
405 1.4 riastrad volatile long double x = trivial_casesl[i];
406 1.3 riastrad
407 1.4 riastrad CHECKL_EQ(i, hypotl, x, +0.L, x);
408 1.4 riastrad CHECKL_EQ(i, hypotl, x, -0.L, x);
409 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, x, x);
410 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, x, x);
411 1.4 riastrad CHECKL_EQ(i, hypotl, -x, +0.L, x);
412 1.4 riastrad CHECKL_EQ(i, hypotl, -x, -0.L, x);
413 1.4 riastrad CHECKL_EQ(i, hypotl, +0.L, -x, x);
414 1.4 riastrad CHECKL_EQ(i, hypotl, -0.L, -x, x);
415 1.6 riastrad
416 1.6 riastrad if (isinf(INFINITY)) {
417 1.6 riastrad CHECKL_EQ(i, hypotl, x, +INFINITY, INFINITY);
418 1.6 riastrad CHECKL_EQ(i, hypotl, x, -INFINITY, INFINITY);
419 1.6 riastrad CHECKL_EQ(i, hypotl, +INFINITY, x, INFINITY);
420 1.6 riastrad CHECKL_EQ(i, hypotl, -INFINITY, x, INFINITY);
421 1.6 riastrad CHECKL_EQ(i, hypotl, -x, +INFINITY, INFINITY);
422 1.6 riastrad CHECKL_EQ(i, hypotl, -x, -INFINITY, INFINITY);
423 1.6 riastrad CHECKL_EQ(i, hypotl, +INFINITY, -x, INFINITY);
424 1.6 riastrad CHECKL_EQ(i, hypotl, -INFINITY, -x, INFINITY);
425 1.6 riastrad }
426 1.6 riastrad
427 1.6 riastrad #ifdef NAN
428 1.6 riastrad if (isinf(x)) {
429 1.6 riastrad CHECKL_EQ(i, hypotl, x, NAN, INFINITY);
430 1.6 riastrad CHECKL_EQ(i, hypotl, NAN, x, INFINITY);
431 1.6 riastrad CHECKL_EQ(i, hypotl, -x, NAN, INFINITY);
432 1.6 riastrad CHECKL_EQ(i, hypotl, NAN, -x, INFINITY);
433 1.6 riastrad } else {
434 1.6 riastrad CHECKL_NAN(i, hypotl, x, NAN);
435 1.6 riastrad CHECKL_NAN(i, hypotl, NAN, x);
436 1.6 riastrad CHECKL_NAN(i, hypotl, -x, NAN);
437 1.6 riastrad CHECKL_NAN(i, hypotl, NAN, -x);
438 1.6 riastrad }
439 1.6 riastrad #endif
440 1.3 riastrad }
441 1.1 gson }
442 1.1 gson
443 1.3 riastrad __CTASSERT(FLT_MANT_DIG >= 24);
444 1.3 riastrad static const struct {
445 1.3 riastrad float a, b, c;
446 1.3 riastrad } exact_casesf[] = {
447 1.3 riastrad { 3, 4, 5 },
448 1.3 riastrad { 5, 12, 13 },
449 1.3 riastrad { 9, 12, 15 },
450 1.3 riastrad { 0x1001, 0x801000, 0x801001 },
451 1.3 riastrad { 4248257, 1130976, 4396225 },
452 1.3 riastrad };
453 1.3 riastrad
454 1.3 riastrad __CTASSERT(DBL_MANT_DIG >= 53);
455 1.3 riastrad static const struct {
456 1.3 riastrad double a, b, c;
457 1.3 riastrad } exact_cases[] = {
458 1.3 riastrad { 3378249543467007, 4505248894795776, 5631148868747265 },
459 1.3 riastrad { 0x7ffffff, 0x1ffffff8000000, 0x1ffffff8000001 },
460 1.3 riastrad #if DBL_MANT_DIG >= 56
461 1.3 riastrad { 13514123525517439, 18018830919909120, 22523538851237761 },
462 1.3 riastrad { 0x1fffffff, 0x1ffffffe0000000, 0x1ffffffe0000001 },
463 1.3 riastrad #endif
464 1.3 riastrad };
465 1.3 riastrad
466 1.3 riastrad #if LDBL_MANT_DIG >= 64
467 1.3 riastrad static const struct {
468 1.3 riastrad long double a, b, c;
469 1.3 riastrad } exact_casesl[] = {
470 1.3 riastrad { 3458976450080784639, 4611968592949214720, 5764960744407842561 },
471 1.3 riastrad { 0x1ffffffff, 0x1fffffffe00000000p0L, 0x1fffffffe00000001p0L },
472 1.3 riastrad #if LDBL_MANT_DIG >= 113
473 1.3 riastrad { 973555668229277869436257492279295.L,
474 1.3 riastrad 1298074224305703705819019479072768.L,
475 1.3 riastrad 1622592780382129686316970078625793.L },
476 1.3 riastrad { 0x1ffffffffffffff,
477 1.3 riastrad 0x1fffffffffffffe00000000000000p0L,
478 1.3 riastrad 0x1fffffffffffffe00000000000001p0L },
479 1.3 riastrad #endif
480 1.3 riastrad };
481 1.3 riastrad #endif
482 1.3 riastrad
483 1.3 riastrad ATF_TC(hypotf_exact);
484 1.3 riastrad ATF_TC_HEAD(hypotf_exact, tc)
485 1.1 gson {
486 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotf on scaled Pythagorean triples");
487 1.3 riastrad }
488 1.3 riastrad ATF_TC_BODY(hypotf_exact, tc)
489 1.3 riastrad {
490 1.3 riastrad unsigned i;
491 1.3 riastrad
492 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
493 1.3 riastrad int s;
494 1.3 riastrad
495 1.3 riastrad for (s = FLT_MIN_EXP;
496 1.3 riastrad s < FLT_MAX_EXP - FLT_MANT_DIG;
497 1.3 riastrad s += (FLT_MAX_EXP - FLT_MANT_DIG - FLT_MIN_EXP)/5) {
498 1.3 riastrad volatile double a = ldexpf(exact_casesf[i].a, s);
499 1.3 riastrad volatile double b = ldexpf(exact_casesf[i].b, s);
500 1.3 riastrad float c = ldexpf(exact_casesf[i].c, s);
501 1.3 riastrad
502 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
503 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
504 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
505 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
506 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
507 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
508 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
509 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
510 1.3 riastrad }
511 1.3 riastrad }
512 1.1 gson }
513 1.1 gson
514 1.3 riastrad ATF_TC(hypot_exact);
515 1.3 riastrad ATF_TC_HEAD(hypot_exact, tc)
516 1.1 gson {
517 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypot on scaled Pythagorean triples");
518 1.3 riastrad }
519 1.3 riastrad ATF_TC_BODY(hypot_exact, tc)
520 1.3 riastrad {
521 1.3 riastrad unsigned i;
522 1.3 riastrad
523 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
524 1.3 riastrad int s;
525 1.3 riastrad
526 1.3 riastrad for (s = DBL_MIN_EXP;
527 1.3 riastrad s < DBL_MAX_EXP - DBL_MANT_DIG;
528 1.3 riastrad s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) {
529 1.3 riastrad volatile double a = ldexp(exact_casesf[i].a, s);
530 1.3 riastrad volatile double b = ldexp(exact_casesf[i].b, s);
531 1.3 riastrad double c = ldexp(exact_casesf[i].c, s);
532 1.3 riastrad
533 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
534 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
535 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
536 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
537 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
538 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
539 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
540 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
541 1.3 riastrad }
542 1.3 riastrad }
543 1.3 riastrad
544 1.3 riastrad for (i = 0; i < __arraycount(exact_cases); i++) {
545 1.3 riastrad int s;
546 1.3 riastrad
547 1.3 riastrad for (s = DBL_MIN_EXP;
548 1.3 riastrad s < DBL_MAX_EXP - DBL_MANT_DIG;
549 1.3 riastrad s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) {
550 1.3 riastrad volatile double a = ldexp(exact_cases[i].a, s);
551 1.3 riastrad volatile double b = ldexp(exact_cases[i].b, s);
552 1.3 riastrad double c = ldexp(exact_cases[i].c, s);
553 1.3 riastrad
554 1.3 riastrad CHECK_EQ(i, hypot, a, b, c);
555 1.3 riastrad CHECK_EQ(i, hypot, b, a, c);
556 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c);
557 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c);
558 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c);
559 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c);
560 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c);
561 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c);
562 1.3 riastrad }
563 1.3 riastrad }
564 1.1 gson }
565 1.1 gson
566 1.3 riastrad ATF_TC(hypotl_exact);
567 1.3 riastrad ATF_TC_HEAD(hypotl_exact, tc)
568 1.1 gson {
569 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotl on scaled Pythagorean triples");
570 1.3 riastrad }
571 1.3 riastrad ATF_TC_BODY(hypotl_exact, tc)
572 1.3 riastrad {
573 1.3 riastrad unsigned i;
574 1.3 riastrad
575 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) {
576 1.3 riastrad int s;
577 1.3 riastrad
578 1.3 riastrad for (s = LDBL_MIN_EXP;
579 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
580 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
581 1.3 riastrad volatile long double a = ldexpl(exact_casesf[i].a, s);
582 1.3 riastrad volatile long double b = ldexpl(exact_casesf[i].b, s);
583 1.3 riastrad long double c = ldexpl(exact_casesf[i].c, s);
584 1.3 riastrad
585 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
586 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
587 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c);
588 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c);
589 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c);
590 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c);
591 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c);
592 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c);
593 1.3 riastrad }
594 1.3 riastrad }
595 1.3 riastrad
596 1.3 riastrad for (i = 0; i < __arraycount(exact_cases); i++) {
597 1.3 riastrad int s;
598 1.3 riastrad
599 1.3 riastrad for (s = LDBL_MIN_EXP;
600 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
601 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
602 1.3 riastrad volatile long double a = ldexpl(exact_cases[i].a, s);
603 1.3 riastrad volatile long double b = ldexpl(exact_cases[i].b, s);
604 1.3 riastrad long double c = ldexpl(exact_cases[i].c, s);
605 1.3 riastrad
606 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
607 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
608 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c);
609 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c);
610 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c);
611 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c);
612 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c);
613 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c);
614 1.3 riastrad }
615 1.3 riastrad }
616 1.3 riastrad
617 1.3 riastrad #if LDBL_MANT_DIG >= 64
618 1.3 riastrad for (i = 0; i < __arraycount(exact_casesl); i++) {
619 1.3 riastrad int s;
620 1.3 riastrad
621 1.3 riastrad for (s = LDBL_MIN_EXP;
622 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG;
623 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) {
624 1.3 riastrad volatile long double a = ldexpl(exact_casesl[i].a, s);
625 1.3 riastrad volatile long double b = ldexpl(exact_casesl[i].b, s);
626 1.3 riastrad long double c = ldexpl(exact_casesl[i].c, s);
627 1.3 riastrad
628 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c);
629 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c);
630 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c);
631 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c);
632 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c);
633 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c);
634 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c);
635 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c);
636 1.3 riastrad }
637 1.3 riastrad }
638 1.3 riastrad #endif
639 1.1 gson }
640 1.1 gson
641 1.6 riastrad ATF_TC(hypot_nan);
642 1.6 riastrad ATF_TC_HEAD(hypot_nan, tc)
643 1.6 riastrad {
644 1.6 riastrad atf_tc_set_md_var(tc, "descr", "hypot/hypotf/hypotl(NAN, NAN)");
645 1.6 riastrad }
646 1.6 riastrad ATF_TC_BODY(hypot_nan, tc)
647 1.6 riastrad {
648 1.6 riastrad #ifdef NAN
649 1.6 riastrad CHECK_NAN(0, hypot, NAN, NAN);
650 1.6 riastrad CHECK_NAN(1, hypotf, NAN, NAN);
651 1.6 riastrad CHECKL_NAN(2, hypotl, NAN, NAN);
652 1.6 riastrad #else
653 1.6 riastrad atf_tc_skip("no NaNs on this architecture");
654 1.6 riastrad #endif
655 1.6 riastrad }
656 1.6 riastrad
657 1.1 gson ATF_TC(pr50698);
658 1.1 gson ATF_TC_HEAD(pr50698, tc)
659 1.1 gson {
660 1.2 jruoho atf_tc_set_md_var(tc, "descr", "Check for the bug of PR lib/50698");
661 1.1 gson }
662 1.1 gson
663 1.1 gson ATF_TC_BODY(pr50698, tc)
664 1.1 gson {
665 1.1 gson volatile float a = 1e-18f;
666 1.1 gson float val = hypotf(a, a);
667 1.1 gson ATF_CHECK(!isinf(val));
668 1.1 gson ATF_CHECK(!isnan(val));
669 1.1 gson }
670 1.1 gson
671 1.1 gson ATF_TP_ADD_TCS(tp)
672 1.1 gson {
673 1.1 gson
674 1.3 riastrad ATF_TP_ADD_TC(tp, hypot_exact);
675 1.3 riastrad ATF_TP_ADD_TC(tp, hypot_trivial);
676 1.3 riastrad ATF_TP_ADD_TC(tp, hypotf_exact);
677 1.3 riastrad ATF_TP_ADD_TC(tp, hypotf_trivial);
678 1.3 riastrad ATF_TP_ADD_TC(tp, hypotl_exact);
679 1.3 riastrad ATF_TP_ADD_TC(tp, hypotl_trivial);
680 1.1 gson ATF_TP_ADD_TC(tp, pr50698);
681 1.1 gson
682 1.1 gson return atf_no_error();
683 1.1 gson }
684