1 1.9 riastrad /* $NetBSD: t_hypot.c,v 1.9 2025/04/07 01:31:18 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.9 riastrad #if __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.9 riastrad #if __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.9 riastrad #if __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.7 riastrad /* 444 1.7 riastrad * All primitive Pythagorean triples are generated from coprime 445 1.7 riastrad * integers m > n > 0 by Euclid's formula, 446 1.7 riastrad * 447 1.7 riastrad * a = m^2 - n^2 448 1.7 riastrad * b = 2 m n, 449 1.7 riastrad * c = m^2 + n^2. 450 1.7 riastrad * 451 1.7 riastrad * We test cases with various different numbers and positions of bits, 452 1.7 riastrad * generated by this formula. 453 1.7 riastrad * 454 1.7 riastrad * If you're curious, you can recover m and n from a, b, and c by 455 1.7 riastrad * 456 1.7 riastrad * m = sqrt((a + c)/2) 457 1.7 riastrad * n = b/2m. 458 1.7 riastrad */ 459 1.7 riastrad 460 1.3 riastrad __CTASSERT(FLT_MANT_DIG >= 24); 461 1.3 riastrad static const struct { 462 1.3 riastrad float a, b, c; 463 1.3 riastrad } exact_casesf[] = { 464 1.3 riastrad { 3, 4, 5 }, 465 1.3 riastrad { 5, 12, 13 }, 466 1.3 riastrad { 9, 12, 15 }, 467 1.3 riastrad { 0x1001, 0x801000, 0x801001 }, 468 1.3 riastrad { 4248257, 1130976, 4396225 }, 469 1.3 riastrad }; 470 1.3 riastrad 471 1.3 riastrad __CTASSERT(DBL_MANT_DIG >= 53); 472 1.3 riastrad static const struct { 473 1.3 riastrad double a, b, c; 474 1.3 riastrad } exact_cases[] = { 475 1.3 riastrad { 3378249543467007, 4505248894795776, 5631148868747265 }, 476 1.3 riastrad { 0x7ffffff, 0x1ffffff8000000, 0x1ffffff8000001 }, 477 1.3 riastrad #if DBL_MANT_DIG >= 56 478 1.3 riastrad { 13514123525517439, 18018830919909120, 22523538851237761 }, 479 1.3 riastrad { 0x1fffffff, 0x1ffffffe0000000, 0x1ffffffe0000001 }, 480 1.3 riastrad #endif 481 1.3 riastrad }; 482 1.3 riastrad 483 1.3 riastrad #if LDBL_MANT_DIG >= 64 484 1.3 riastrad static const struct { 485 1.3 riastrad long double a, b, c; 486 1.3 riastrad } exact_casesl[] = { 487 1.3 riastrad { 3458976450080784639, 4611968592949214720, 5764960744407842561 }, 488 1.7 riastrad { 0x200000000, 0x7ffffffffffffffe, 0x8000000000000002 }, 489 1.3 riastrad #if LDBL_MANT_DIG >= 113 490 1.3 riastrad { 973555668229277869436257492279295.L, 491 1.3 riastrad 1298074224305703705819019479072768.L, 492 1.3 riastrad 1622592780382129686316970078625793.L }, 493 1.3 riastrad { 0x1ffffffffffffff, 494 1.3 riastrad 0x1fffffffffffffe00000000000000p0L, 495 1.3 riastrad 0x1fffffffffffffe00000000000001p0L }, 496 1.3 riastrad #endif 497 1.3 riastrad }; 498 1.3 riastrad #endif 499 1.3 riastrad 500 1.3 riastrad ATF_TC(hypotf_exact); 501 1.3 riastrad ATF_TC_HEAD(hypotf_exact, tc) 502 1.1 gson { 503 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotf on scaled Pythagorean triples"); 504 1.3 riastrad } 505 1.3 riastrad ATF_TC_BODY(hypotf_exact, tc) 506 1.3 riastrad { 507 1.3 riastrad unsigned i; 508 1.3 riastrad 509 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) { 510 1.3 riastrad int s; 511 1.3 riastrad 512 1.3 riastrad for (s = FLT_MIN_EXP; 513 1.3 riastrad s < FLT_MAX_EXP - FLT_MANT_DIG; 514 1.3 riastrad s += (FLT_MAX_EXP - FLT_MANT_DIG - FLT_MIN_EXP)/5) { 515 1.3 riastrad volatile double a = ldexpf(exact_casesf[i].a, s); 516 1.3 riastrad volatile double b = ldexpf(exact_casesf[i].b, s); 517 1.3 riastrad float c = ldexpf(exact_casesf[i].c, s); 518 1.3 riastrad 519 1.3 riastrad CHECK_EQ(i, hypot, a, b, c); 520 1.3 riastrad CHECK_EQ(i, hypot, b, a, c); 521 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c); 522 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c); 523 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c); 524 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c); 525 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c); 526 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c); 527 1.3 riastrad } 528 1.3 riastrad } 529 1.1 gson } 530 1.1 gson 531 1.3 riastrad ATF_TC(hypot_exact); 532 1.3 riastrad ATF_TC_HEAD(hypot_exact, tc) 533 1.1 gson { 534 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypot on scaled Pythagorean triples"); 535 1.3 riastrad } 536 1.3 riastrad ATF_TC_BODY(hypot_exact, tc) 537 1.3 riastrad { 538 1.3 riastrad unsigned i; 539 1.3 riastrad 540 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) { 541 1.3 riastrad int s; 542 1.3 riastrad 543 1.3 riastrad for (s = DBL_MIN_EXP; 544 1.3 riastrad s < DBL_MAX_EXP - DBL_MANT_DIG; 545 1.3 riastrad s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) { 546 1.3 riastrad volatile double a = ldexp(exact_casesf[i].a, s); 547 1.3 riastrad volatile double b = ldexp(exact_casesf[i].b, s); 548 1.3 riastrad double c = ldexp(exact_casesf[i].c, s); 549 1.3 riastrad 550 1.3 riastrad CHECK_EQ(i, hypot, a, b, c); 551 1.3 riastrad CHECK_EQ(i, hypot, b, a, c); 552 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c); 553 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c); 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 } 559 1.3 riastrad } 560 1.3 riastrad 561 1.3 riastrad for (i = 0; i < __arraycount(exact_cases); i++) { 562 1.3 riastrad int s; 563 1.3 riastrad 564 1.3 riastrad for (s = DBL_MIN_EXP; 565 1.3 riastrad s < DBL_MAX_EXP - DBL_MANT_DIG; 566 1.3 riastrad s += (DBL_MAX_EXP - DBL_MANT_DIG - DBL_MIN_EXP)/5) { 567 1.3 riastrad volatile double a = ldexp(exact_cases[i].a, s); 568 1.3 riastrad volatile double b = ldexp(exact_cases[i].b, s); 569 1.3 riastrad double c = ldexp(exact_cases[i].c, s); 570 1.3 riastrad 571 1.3 riastrad CHECK_EQ(i, hypot, a, b, c); 572 1.3 riastrad CHECK_EQ(i, hypot, b, a, c); 573 1.3 riastrad CHECK_EQ(i, hypot, a, -b, c); 574 1.3 riastrad CHECK_EQ(i, hypot, b, -a, c); 575 1.3 riastrad CHECK_EQ(i, hypot, -a, b, c); 576 1.3 riastrad CHECK_EQ(i, hypot, -b, a, c); 577 1.3 riastrad CHECK_EQ(i, hypot, -a, -b, c); 578 1.3 riastrad CHECK_EQ(i, hypot, -b, -a, c); 579 1.3 riastrad } 580 1.3 riastrad } 581 1.1 gson } 582 1.1 gson 583 1.3 riastrad ATF_TC(hypotl_exact); 584 1.3 riastrad ATF_TC_HEAD(hypotl_exact, tc) 585 1.1 gson { 586 1.3 riastrad atf_tc_set_md_var(tc, "descr", "hypotl on scaled Pythagorean triples"); 587 1.3 riastrad } 588 1.3 riastrad ATF_TC_BODY(hypotl_exact, tc) 589 1.3 riastrad { 590 1.3 riastrad unsigned i; 591 1.3 riastrad 592 1.3 riastrad for (i = 0; i < __arraycount(exact_casesf); i++) { 593 1.3 riastrad int s; 594 1.3 riastrad 595 1.3 riastrad for (s = LDBL_MIN_EXP; 596 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG; 597 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) { 598 1.3 riastrad volatile long double a = ldexpl(exact_casesf[i].a, s); 599 1.3 riastrad volatile long double b = ldexpl(exact_casesf[i].b, s); 600 1.3 riastrad long double c = ldexpl(exact_casesf[i].c, s); 601 1.3 riastrad 602 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c); 603 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c); 604 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c); 605 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c); 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 } 611 1.3 riastrad } 612 1.3 riastrad 613 1.3 riastrad for (i = 0; i < __arraycount(exact_cases); i++) { 614 1.3 riastrad int s; 615 1.3 riastrad 616 1.3 riastrad for (s = LDBL_MIN_EXP; 617 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG; 618 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) { 619 1.3 riastrad volatile long double a = ldexpl(exact_cases[i].a, s); 620 1.3 riastrad volatile long double b = ldexpl(exact_cases[i].b, s); 621 1.3 riastrad long double c = ldexpl(exact_cases[i].c, s); 622 1.3 riastrad 623 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c); 624 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c); 625 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c); 626 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c); 627 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c); 628 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c); 629 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c); 630 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c); 631 1.3 riastrad } 632 1.3 riastrad } 633 1.3 riastrad 634 1.3 riastrad #if LDBL_MANT_DIG >= 64 635 1.3 riastrad for (i = 0; i < __arraycount(exact_casesl); i++) { 636 1.3 riastrad int s; 637 1.3 riastrad 638 1.3 riastrad for (s = LDBL_MIN_EXP; 639 1.3 riastrad s < LDBL_MAX_EXP - LDBL_MANT_DIG; 640 1.3 riastrad s += (LDBL_MAX_EXP - LDBL_MANT_DIG - LDBL_MIN_EXP)/5) { 641 1.3 riastrad volatile long double a = ldexpl(exact_casesl[i].a, s); 642 1.3 riastrad volatile long double b = ldexpl(exact_casesl[i].b, s); 643 1.3 riastrad long double c = ldexpl(exact_casesl[i].c, s); 644 1.3 riastrad 645 1.3 riastrad CHECKL_EQ(i, hypotl, a, b, c); 646 1.3 riastrad CHECKL_EQ(i, hypotl, b, a, c); 647 1.3 riastrad CHECKL_EQ(i, hypotl, a, -b, c); 648 1.3 riastrad CHECKL_EQ(i, hypotl, b, -a, c); 649 1.3 riastrad CHECKL_EQ(i, hypotl, -a, b, c); 650 1.3 riastrad CHECKL_EQ(i, hypotl, -b, a, c); 651 1.3 riastrad CHECKL_EQ(i, hypotl, -a, -b, c); 652 1.3 riastrad CHECKL_EQ(i, hypotl, -b, -a, c); 653 1.3 riastrad } 654 1.3 riastrad } 655 1.3 riastrad #endif 656 1.1 gson } 657 1.1 gson 658 1.6 riastrad ATF_TC(hypot_nan); 659 1.6 riastrad ATF_TC_HEAD(hypot_nan, tc) 660 1.6 riastrad { 661 1.6 riastrad atf_tc_set_md_var(tc, "descr", "hypot/hypotf/hypotl(NAN, NAN)"); 662 1.6 riastrad } 663 1.6 riastrad ATF_TC_BODY(hypot_nan, tc) 664 1.6 riastrad { 665 1.6 riastrad #ifdef NAN 666 1.6 riastrad CHECK_NAN(0, hypot, NAN, NAN); 667 1.6 riastrad CHECK_NAN(1, hypotf, NAN, NAN); 668 1.6 riastrad CHECKL_NAN(2, hypotl, NAN, NAN); 669 1.6 riastrad #else 670 1.6 riastrad atf_tc_skip("no NaNs on this architecture"); 671 1.6 riastrad #endif 672 1.6 riastrad } 673 1.6 riastrad 674 1.1 gson ATF_TC(pr50698); 675 1.1 gson ATF_TC_HEAD(pr50698, tc) 676 1.1 gson { 677 1.2 jruoho atf_tc_set_md_var(tc, "descr", "Check for the bug of PR lib/50698"); 678 1.1 gson } 679 1.1 gson 680 1.1 gson ATF_TC_BODY(pr50698, tc) 681 1.1 gson { 682 1.1 gson volatile float a = 1e-18f; 683 1.1 gson float val = hypotf(a, a); 684 1.1 gson ATF_CHECK(!isinf(val)); 685 1.1 gson ATF_CHECK(!isnan(val)); 686 1.1 gson } 687 1.1 gson 688 1.1 gson ATF_TP_ADD_TCS(tp) 689 1.1 gson { 690 1.1 gson 691 1.3 riastrad ATF_TP_ADD_TC(tp, hypot_exact); 692 1.8 rillig ATF_TP_ADD_TC(tp, hypot_nan); 693 1.3 riastrad ATF_TP_ADD_TC(tp, hypot_trivial); 694 1.3 riastrad ATF_TP_ADD_TC(tp, hypotf_exact); 695 1.3 riastrad ATF_TP_ADD_TC(tp, hypotf_trivial); 696 1.3 riastrad ATF_TP_ADD_TC(tp, hypotl_exact); 697 1.3 riastrad ATF_TP_ADD_TC(tp, hypotl_trivial); 698 1.1 gson ATF_TP_ADD_TC(tp, pr50698); 699 1.1 gson 700 1.1 gson return atf_no_error(); 701 1.1 gson } 702