1 /* $NetBSD: t_log.c,v 1.17 2024/07/16 03:14:16 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jukka Ruohonen. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 #include <sys/cdefs.h> 32 __RCSID("$NetBSD: t_log.c,v 1.17 2024/07/16 03:14:16 riastradh Exp $"); 33 34 #include <sys/types.h> 35 36 #include <atf-c.h> 37 38 #include <errno.h> 39 #include <float.h> 40 #include <math.h> 41 #include <stdio.h> 42 #include <string.h> 43 44 #define CHECK_EQ(i, f, x, y) \ 45 ATF_CHECK_EQ_MSG(f(x), y, \ 46 "[%u] %s(%a=%.17g)=%a=%.17g, expected %a=%.17g", \ 47 (i), #f, (double)(x), (double)(x), f(x), f(x), \ 48 (double)(y), (double)(y)) 49 50 #define CHECKL_EQ(i, f, x, y) \ 51 ATF_CHECK_EQ_MSG(f(x), y, \ 52 "[%u] %s(%La=%.34Lg)=%La=%.34Lg, expected %La=%.34Lg", \ 53 (i), #f, (long double)(x), (long double)(x), f(x), f(x), \ 54 (long double)(y), (long double)(y)) 55 56 #ifdef NAN 57 58 #define CHECK_NAN(i, f, x) \ 59 ATF_CHECK_MSG(isnan(f(x)), \ 60 "[%u] %s(%a=%.17g)=%a=%.17g, expected NaN", \ 61 (i), #f, (x), (x), f(x), f(x)) 62 63 #define CHECKL_NAN(i, f, x) \ 64 ATF_CHECK_MSG(isnan(f(x)), \ 65 "[%u] %s(%La=%.34Lg)=%La=%.34Lg, expected NaN", \ 66 (i), #f, (long double)(x), (long double)(x), f(x), f(x)) 67 68 #else /* !defined(NAN) */ 69 70 #define CHECK_NAN(i, f, x) do \ 71 { \ 72 int _checknan_error; \ 73 double _checknan_result; \ 74 errno = 0; \ 75 _checknan_result = f(x); \ 76 _checknan_error = errno; \ 77 ATF_CHECK_EQ_MSG(errno, EDOM, \ 78 "[%u] %s(%a=%.17g)=%a=%.17g errno=%d, expected EDOM=%d", \ 79 (i), #f, (double)(x), (double)(x), \ 80 _checknan_result, _checknan_result, \ 81 _checknan_error, EDOM); \ 82 } while (0) 83 84 #define CHECKL_NAN(i, f, x) do \ 85 { \ 86 int _checknan_error; \ 87 long double _checknan_result; \ 88 errno = 0; \ 89 _checknan_result = f(x); \ 90 _checknan_error = errno; \ 91 ATF_CHECK_EQ_MSG(errno, EDOM, \ 92 "[%u] %s(%La=%.34Lg)=%La=%.34Lg errno=%d, expected EDOM=%d", \ 93 (i), #f, (long double)(x), (long double)(x), \ 94 _checknan_result, _checknan_result, \ 95 _checknan_error, EDOM); \ 96 } while (0) 97 98 #endif /* NAN */ 99 100 static const float logf_invalid[] = { 101 #ifdef NAN 102 NAN, 103 #endif 104 -HUGE_VALF, 105 -FLT_MAX, 106 -10, 107 -1, 108 -FLT_EPSILON, 109 -FLT_MIN, 110 #ifdef FLT_DENORM_MIN 111 -FLT_DENORM_MIN, 112 #endif 113 }; 114 115 static const double log_invalid[] = { 116 #ifdef NAN 117 NAN, 118 #endif 119 -HUGE_VAL, 120 -DBL_MAX, 121 -10, 122 -1, 123 -DBL_EPSILON, 124 -DBL_MIN, 125 #ifdef DBL_DENORM_MIN 126 -DBL_DENORM_MIN, 127 #endif 128 }; 129 130 static const long double logl_invalid[] = { 131 #ifdef NAN 132 NAN, 133 #endif 134 -HUGE_VALL, 135 -LDBL_MAX, 136 -10, 137 -1, 138 -LDBL_EPSILON, 139 -LDBL_MIN, 140 #ifdef LDBL_DENORM_MIN 141 -LDBL_DENORM_MIN, 142 #endif 143 }; 144 145 static const float log1pf_invalid[] = { 146 #ifdef NAN 147 NAN, 148 #endif 149 -HUGE_VALF, 150 -FLT_MAX, 151 -10, 152 -1 - FLT_EPSILON, 153 }; 154 155 static const double log1p_invalid[] = { 156 #ifdef NAN 157 NAN, 158 #endif 159 -HUGE_VAL, 160 -DBL_MAX, 161 -10, 162 -1 - DBL_EPSILON, 163 }; 164 165 static const long double log1pl_invalid[] = { 166 #ifdef NAN 167 NAN, 168 #endif 169 -HUGE_VALL, 170 -LDBL_MAX, 171 -10, 172 -1 - LDBL_EPSILON, 173 }; 174 175 /* 176 * log10(3) 177 */ 178 static const struct { 179 float x, y; 180 } log10f_exact[] = { 181 { 1, 0 }, 182 { 10, 1 }, 183 { 100, 2 }, 184 }; 185 186 ATF_TC(log10_invalid); 187 ATF_TC_HEAD(log10_invalid, tc) 188 { 189 atf_tc_set_md_var(tc, "descr", "Test log10/f/l on invalid inputs"); 190 } 191 ATF_TC_BODY(log10_invalid, tc) 192 { 193 unsigned i; 194 195 for (i = 0; i < __arraycount(logf_invalid); i++) { 196 CHECK_NAN(i, log10f, logf_invalid[i]); 197 CHECK_NAN(i, log10, logf_invalid[i]); 198 CHECKL_NAN(i, log10l, logf_invalid[i]); 199 } 200 201 for (i = 0; i < __arraycount(log_invalid); i++) { 202 CHECK_NAN(i, log10, log_invalid[i]); 203 CHECKL_NAN(i, log10l, log_invalid[i]); 204 } 205 206 for (i = 0; i < __arraycount(logl_invalid); i++) { 207 CHECKL_NAN(i, log10l, logl_invalid[i]); 208 } 209 } 210 211 ATF_TC(log10_zero); 212 ATF_TC_HEAD(log10_zero, tc) 213 { 214 atf_tc_set_md_var(tc, "descr", "Test log10/f/l on zero"); 215 } 216 ATF_TC_BODY(log10_zero, tc) 217 { 218 219 CHECK_EQ(0, log10f, +0., -HUGE_VALF); 220 CHECK_EQ(0, log10, +0., -HUGE_VAL); 221 CHECKL_EQ(0, log10l, +0., -HUGE_VALL); 222 223 CHECK_EQ(1, log10f, -0., -HUGE_VALF); 224 CHECK_EQ(1, log10, -0., -HUGE_VAL); 225 CHECKL_EQ(1, log10l, -0., -HUGE_VALL); 226 } 227 228 ATF_TC(log10_exact); 229 ATF_TC_HEAD(log10_exact, tc) 230 { 231 atf_tc_set_md_var(tc, "descr", "Test log10/f/l exact cases"); 232 } 233 ATF_TC_BODY(log10_exact, tc) 234 { 235 unsigned i; 236 237 ATF_CHECK_EQ(signbit(log10f(1)), 0); 238 ATF_CHECK_EQ(signbit(log10(1)), 0); 239 ATF_CHECK_EQ(signbit(log10l(1)), 0); 240 241 #if __HAVE_LONG_DOUBLE + 0 == 128 242 /* 243 * Not sure if it's the same issue, but probably! 244 * 245 * log10l(x) != y: [1] log10l(0x1.4p+3=10)=0x1.ffffffffcf54a625cf632f6e120dp-1=0.99999999997786775, expected 0x1p+0=1 246 * log10l(x) != y: [2] log10l(0x1.9p+6=100)=0x1.ffffc6bdc46c7020e9b1f5a2930ep+0=1.9999965871142409, expected 0x1p+1=2 247 */ 248 atf_tc_expect_fail("PR lib/58337: logl() crashes on arm64"); 249 #endif 250 251 for (i = 0; i < __arraycount(log10f_exact); i++) { 252 const float x = log10f_exact[i].x; 253 const float y = log10f_exact[i].y; 254 255 CHECK_EQ(i, log10f, x, y); 256 CHECK_EQ(i, log10, x, y); 257 CHECKL_EQ(i, log10l, x, y); 258 } 259 } 260 261 ATF_TC(log10_approx); 262 ATF_TC_HEAD(log10_approx, tc) 263 { 264 atf_tc_set_md_var(tc, "descr", "Test log10/f/l approximate cases"); 265 } 266 ATF_TC_BODY(log10_approx, tc) 267 { 268 volatile long double e = 269 2.7182818284590452353602874713526624977572470937L; 270 volatile long double e2 = 271 7.3890560989306502272304274605750078131803155705519L; 272 volatile long double log10e = 273 0.43429448190325182765112891891660508229439700580367L; 274 volatile long double log10e2 = 275 2*0.43429448190325182765112891891660508229439700580367L; 276 277 #if __HAVE_LONG_DOUBLE + 0 == 128 278 atf_tc_expect_fail("PR lib/58337: logl() crashes on arm64"); 279 #endif 280 281 ATF_CHECK_MSG((fabsf((log10f(e) - (float)log10e)/(float)log10e) < 282 2*FLT_EPSILON), 283 "log10f(e)=%a=%.8g expected %a=%.8g", 284 log10f(e), log10f(e), (float)log10e, (float)log10e); 285 ATF_CHECK_MSG((fabs((log10(e) - (double)log10e)/(double)log10e) < 286 2*DBL_EPSILON), 287 "log10(e)=%a=%.17g expected %a=%.17g", 288 log10(e), log10(e), (double)log10e, (double)log10e); 289 ATF_CHECK_MSG((fabsl((log10l(e) - log10e)/log10e) < 2*LDBL_EPSILON), 290 "log10l(e)=%La=%.34Lg expected %La=%.34Lg", 291 log10l(e), log10l(e), log10e, log10e); 292 293 ATF_CHECK_MSG((fabsf((log10f(e2) - (float)log10e2)/(float)log10e2) < 294 2*FLT_EPSILON), 295 "log10f(e^2)=%a=%.8g expected %a=%.8g", 296 log10f(e2), log10f(e2), (float)log10e2, (float)log10e2); 297 ATF_CHECK_MSG((fabs((log10(e2) - (double)log10e2)/(double)log10e2) < 298 2*DBL_EPSILON), 299 "log10(e^2)=%a=%.17g expected %a=%.17g", 300 log10(e2), log10(e2), (double)log10e2, (double)log10e2); 301 ATF_CHECK_MSG((fabsl((log10l(e2) - log10e2)/log10e2) < 2*LDBL_EPSILON), 302 "log10l(e^2)=%La=%.34Lg expected %La=%.34Lg", 303 log10l(e2), log10l(e2), log10e2, log10e2); 304 } 305 306 ATF_TC(log10_inf); 307 ATF_TC_HEAD(log10_inf, tc) 308 { 309 atf_tc_set_md_var(tc, "descr", "Test log10/f/l on +infinity"); 310 } 311 ATF_TC_BODY(log10_inf, tc) 312 { 313 314 if (!isinf(INFINITY)) 315 atf_tc_skip("no infinities on this architecture"); 316 317 CHECK_EQ(0, log10f, INFINITY, INFINITY); 318 CHECK_EQ(0, log10, INFINITY, INFINITY); 319 CHECKL_EQ(0, log10l, INFINITY, INFINITY); 320 } 321 322 /* 323 * log1p(3) 324 */ 325 326 ATF_TC(log1p_invalid); 327 ATF_TC_HEAD(log1p_invalid, tc) 328 { 329 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on invalid inputs"); 330 } 331 ATF_TC_BODY(log1p_invalid, tc) 332 { 333 unsigned i; 334 335 for (i = 0; i < __arraycount(log1pf_invalid); i++) { 336 CHECK_NAN(i, log1pf, log1pf_invalid[i]); 337 CHECK_NAN(i, log1p, log1pf_invalid[i]); 338 CHECKL_NAN(i, log1pl, log1pf_invalid[i]); 339 } 340 341 for (i = 0; i < __arraycount(log1p_invalid); i++) { 342 CHECK_NAN(i, log1p, log1p_invalid[i]); 343 CHECKL_NAN(i, log1pl, log1p_invalid[i]); 344 } 345 346 for (i = 0; i < __arraycount(log1pl_invalid); i++) { 347 CHECKL_NAN(i, log1pl, log1pl_invalid[i]); 348 } 349 } 350 351 ATF_TC(log1p_neg_one); 352 ATF_TC_HEAD(log1p_neg_one, tc) 353 { 354 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on -1"); 355 } 356 ATF_TC_BODY(log1p_neg_one, tc) 357 { 358 359 CHECK_EQ(0, log1pf, -1., -HUGE_VALF); 360 CHECK_EQ(0, log1p, -1., -HUGE_VAL); 361 CHECKL_EQ(0, log1pl, -1., -HUGE_VALL); 362 } 363 364 ATF_TC(log1p_exact); 365 ATF_TC_HEAD(log1p_exact, tc) 366 { 367 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l exact cases"); 368 } 369 ATF_TC_BODY(log1p_exact, tc) 370 { 371 372 CHECK_EQ(0, log1pf, -FLT_MIN, -FLT_MIN); 373 CHECK_EQ(0, log1p, -DBL_MIN, -DBL_MIN); 374 CHECKL_EQ(01, log1pl, -LDBL_MIN, -LDBL_MIN); 375 376 CHECK_EQ(1, log1pf, -0., 0); 377 CHECK_EQ(1, log1p, -0., 0); 378 CHECKL_EQ(1, log1pl, -0., 0); 379 380 CHECK_EQ(2, log1pf, +0., 0); 381 CHECK_EQ(2, log1p, +0., 0); 382 CHECKL_EQ(2, log1pl, +0., 0); 383 384 CHECK_EQ(3, log1pf, 1, logf(2)); 385 CHECK_EQ(3, log1p, 1, log(2)); 386 CHECKL_EQ(3, log1pl, 1, logl(2)); 387 } 388 389 ATF_TC(log1p_approx); 390 ATF_TC_HEAD(log1p_approx, tc) 391 { 392 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l approximate cases"); 393 } 394 ATF_TC_BODY(log1p_approx, tc) 395 { 396 volatile long double em1 = /* exp(1) - 1 */ 397 1.7182818284590452353602874713526624977572470937L; 398 volatile long double e2m1 = /* exp(2) - 1 */ 399 6.3890560989306502272304274605750078131803155705519L; 400 401 #if __HAVE_LONG_DOUBLE + 0 == 128 402 atf_tc_expect_fail("PR lib/58337: logl() crashes on arm64"); 403 #endif 404 405 /* 406 * Approximation is close enough that equality of the rounded 407 * output had better hold. 408 */ 409 #ifdef FLT_DENORM_MIN 410 CHECK_EQ(0, log1pf, -FLT_DENORM_MIN, -FLT_DENORM_MIN); 411 #endif 412 #ifdef DBL_DENORM_MIN 413 CHECK_EQ(0, log1p, -DBL_DENORM_MIN, -DBL_DENORM_MIN); 414 #endif 415 #ifdef LDBL_DENORM_MIN 416 CHECKL_EQ(0, log1pl, -LDBL_DENORM_MIN, -LDBL_DENORM_MIN); 417 #endif 418 419 ATF_CHECK_MSG(fabsf((log1pf(em1) - 1)/1) < 2*FLT_EPSILON, 420 "log1pf(e)=%a=%.8g", log1pf(em1), log1pf(em1)); 421 ATF_CHECK_MSG(fabs((log1p(em1) - 1)/1) < 2*DBL_EPSILON, 422 "log1p(e)=%a=%.17g", log1p(em1), log1p(em1)); 423 ATF_CHECK_MSG(fabsl((log1pl(em1) - 1)/1) < 2*LDBL_EPSILON, 424 "log1pl(e)=%La=%.34Lg", log1pl(em1), log1pl(em1)); 425 426 ATF_CHECK_MSG(fabsf((log1pf(e2m1) - 2)/2) < 2*FLT_EPSILON, 427 "log1pf(e^2)=%a=%.8g", log1pf(em1), log1pf(em1)); 428 ATF_CHECK_MSG(fabs((log1p(e2m1) - 2)/2) < 2*DBL_EPSILON, 429 "log1p(e^2)=%a=%.17g", log1p(em1), log1p(em1)); 430 ATF_CHECK_MSG(fabsl((log1pl(e2m1) - 2)/2) < 2*LDBL_EPSILON, 431 "log1pl(e^2)=%La=%.34Lg", log1pl(em1), log1pl(em1)); 432 } 433 434 ATF_TC(log1p_inf); 435 ATF_TC_HEAD(log1p_inf, tc) 436 { 437 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on +infinity"); 438 } 439 ATF_TC_BODY(log1p_inf, tc) 440 { 441 442 if (!isinf(INFINITY)) 443 atf_tc_skip("no infinities on this architecture"); 444 445 CHECK_EQ(0, log1pf, INFINITY, INFINITY); 446 CHECK_EQ(0, log1p, INFINITY, INFINITY); 447 CHECKL_EQ(0, log1pl, INFINITY, INFINITY); 448 } 449 450 /* 451 * log2(3) 452 */ 453 static const struct { 454 float x, y; 455 } log2f_exact[] = { 456 #ifdef FLT_DENORM_MIN 457 { FLT_DENORM_MIN, FLT_MIN_EXP - FLT_MANT_DIG }, 458 #endif 459 { FLT_MIN, FLT_MIN_EXP - 1 }, 460 { 0.25, -2 }, 461 { 0.5, -1 }, 462 { 1, 0 }, 463 { 2, 1 }, 464 { 4, 2 }, 465 { 8, 3 }, 466 { 1 << FLT_MANT_DIG, FLT_MANT_DIG }, 467 { (float)(1 << FLT_MANT_DIG) * (1 << FLT_MANT_DIG), 468 2*FLT_MANT_DIG }, 469 }; 470 static const struct { 471 double x, y; 472 } log2_exact[] = { 473 #ifdef DBL_DENORM_MIN 474 { DBL_DENORM_MIN, DBL_MIN_EXP - DBL_MANT_DIG }, 475 #endif 476 { DBL_MIN, DBL_MIN_EXP - 1 }, 477 { (uint64_t)1 << DBL_MANT_DIG, DBL_MANT_DIG }, 478 { ((double)((uint64_t)1 << DBL_MANT_DIG) * 479 ((uint64_t)1 << DBL_MANT_DIG)), 480 2*DBL_MANT_DIG }, 481 }; 482 483 static const struct { 484 long double x, y; 485 } log2l_exact[] = { 486 #ifdef LDBL_DENORM_MIN 487 { LDBL_DENORM_MIN, LDBL_MIN_EXP - LDBL_MANT_DIG }, 488 #endif 489 { LDBL_MIN, LDBL_MIN_EXP - 1 }, 490 { ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) * 491 ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))), 492 LDBL_MANT_DIG }, 493 { (((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) * 494 ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))) * 495 ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) * 496 ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2)))), 497 2*LDBL_MANT_DIG }, 498 }; 499 500 ATF_TC(log2_invalid); 501 ATF_TC_HEAD(log2_invalid, tc) 502 { 503 atf_tc_set_md_var(tc, "descr", "Test log2/f/l on invalid inputs"); 504 } 505 ATF_TC_BODY(log2_invalid, tc) 506 { 507 unsigned i; 508 509 for (i = 0; i < __arraycount(logf_invalid); i++) { 510 CHECK_NAN(i, log2f, logf_invalid[i]); 511 CHECK_NAN(i, log2, logf_invalid[i]); 512 CHECKL_NAN(i, log2l, logf_invalid[i]); 513 } 514 515 for (i = 0; i < __arraycount(log_invalid); i++) { 516 CHECK_NAN(i, log2, log_invalid[i]); 517 CHECKL_NAN(i, log2l, log_invalid[i]); 518 } 519 520 for (i = 0; i < __arraycount(logl_invalid); i++) { 521 CHECKL_NAN(i, log2l, logl_invalid[i]); 522 } 523 } 524 525 ATF_TC(log2_zero); 526 ATF_TC_HEAD(log2_zero, tc) 527 { 528 atf_tc_set_md_var(tc, "descr", "Test log2/f/l on zero"); 529 } 530 ATF_TC_BODY(log2_zero, tc) 531 { 532 533 CHECK_EQ(0, log2f, +0., -HUGE_VALF); 534 CHECK_EQ(0, log2, +0., -HUGE_VAL); 535 CHECKL_EQ(0, log2l, +0., -HUGE_VALL); 536 537 CHECK_EQ(1, log2f, -0., -HUGE_VALF); 538 CHECK_EQ(1, log2, -0., -HUGE_VAL); 539 CHECKL_EQ(1, log2l, -0., -HUGE_VALL); 540 } 541 542 ATF_TC(log2_exact); 543 ATF_TC_HEAD(log2_exact, tc) 544 { 545 atf_tc_set_md_var(tc, "descr", "Test log2/f/l exact cases"); 546 } 547 ATF_TC_BODY(log2_exact, tc) 548 { 549 unsigned i; 550 551 ATF_CHECK_EQ(signbit(log2f(1)), 0); 552 ATF_CHECK_EQ(signbit(log2(1)), 0); 553 ATF_CHECK_EQ(signbit(log2l(1)), 0); 554 555 for (i = 0; i < __arraycount(log2f_exact); i++) { 556 const float x = log2f_exact[i].x; 557 const float y = log2f_exact[i].y; 558 559 CHECK_EQ(i, log2f, x, y); 560 CHECK_EQ(i, log2, x, y); 561 CHECKL_EQ(i, log2l, x, y); 562 } 563 564 for (i = 0; i < __arraycount(log2_exact); i++) { 565 const double x = log2_exact[i].x; 566 const double y = log2_exact[i].y; 567 568 CHECK_EQ(i, log2, x, y); 569 CHECKL_EQ(i, log2l, x, y); 570 } 571 572 for (i = 0; i < __arraycount(log2l_exact); i++) { 573 const long double x = log2l_exact[i].x; 574 const long double y = log2l_exact[i].y; 575 576 CHECKL_EQ(i, log2l, x, y); 577 } 578 } 579 580 ATF_TC(log2_approx); 581 ATF_TC_HEAD(log2_approx, tc) 582 { 583 atf_tc_set_md_var(tc, "descr", "Test log2/f/l approximate cases"); 584 } 585 ATF_TC_BODY(log2_approx, tc) 586 { 587 volatile long double e = 588 2.7182818284590452353602874713526624977572470937L; 589 volatile long double e2 = 590 7.3890560989306502272304274605750078131803155705519L; 591 volatile long double log2e = 592 1.442695040888963407359924681001892137426645954153L; 593 volatile long double log2e2 = 594 2*1.442695040888963407359924681001892137426645954153L; 595 596 #if __HAVE_LONG_DOUBLE + 0 == 128 597 atf_tc_expect_fail("PR lib/58337: logl() crashes on arm64"); 598 #endif 599 600 ATF_CHECK_MSG((fabsf((log2f(e) - (float)log2e)/(float)log2e) < 601 2*FLT_EPSILON), 602 "log2f(e)=%a=%.8g expected %a=%.8g", 603 log2f(e), log2f(e), (float)log2e, (float)log2e); 604 ATF_CHECK_MSG((fabs((log2(e) - (double)log2e)/(double)log2e) < 605 2*DBL_EPSILON), 606 "log2(e)=%a=%.17g expected %a=%.17g", 607 log2(e), log2(e), (double)log2e, (double)log2e); 608 ATF_CHECK_MSG((fabsl((log2l(e) - log2e)/log2e) < 2*LDBL_EPSILON), 609 "log2l(e)=%La=%.34Lg expected %La=%.34Lg", 610 log2l(e), log2l(e), log2e, log2e); 611 612 ATF_CHECK_MSG((fabsf((log2f(e2) - (float)log2e2)/(float)log2e2) < 613 2*FLT_EPSILON), 614 "log2f(e^2)=%a=%.8g expected %a=%.8g", 615 log2f(e2), log2f(e2), (float)log2e2, (float)log2e2); 616 ATF_CHECK_MSG((fabs((log2(e2) - (double)log2e2)/(double)log2e2) < 617 2*DBL_EPSILON), 618 "log2(e^2)=%a=%.17g expected %a=%.17g", 619 log2(e2), log2(e2), (double)log2e2, (double)log2e2); 620 ATF_CHECK_MSG((fabsl((log2l(e2) - log2e2)/log2e2) < 2*LDBL_EPSILON), 621 "log2l(e^2)=%La=%.34Lg expected %La=%.34Lg", 622 log2l(e2), log2l(e2), log2e2, log2e2); 623 } 624 625 ATF_TC(log2_inf); 626 ATF_TC_HEAD(log2_inf, tc) 627 { 628 atf_tc_set_md_var(tc, "descr", "Test log2/f/l on +infinity"); 629 } 630 ATF_TC_BODY(log2_inf, tc) 631 { 632 633 if (!isinf(INFINITY)) 634 atf_tc_skip("no infinities on this architecture"); 635 636 CHECK_EQ(0, log2f, INFINITY, INFINITY); 637 CHECK_EQ(0, log2, INFINITY, INFINITY); 638 CHECKL_EQ(0, log2l, INFINITY, INFINITY); 639 } 640 641 /* 642 * log(3) 643 */ 644 645 ATF_TC(log_invalid); 646 ATF_TC_HEAD(log_invalid, tc) 647 { 648 atf_tc_set_md_var(tc, "descr", "Test log/f/l on invalid inputs"); 649 } 650 ATF_TC_BODY(log_invalid, tc) 651 { 652 unsigned i; 653 654 for (i = 0; i < __arraycount(logf_invalid); i++) { 655 CHECK_NAN(i, logf, logf_invalid[i]); 656 CHECK_NAN(i, log, logf_invalid[i]); 657 CHECKL_NAN(i, logl, logf_invalid[i]); 658 } 659 660 for (i = 0; i < __arraycount(log_invalid); i++) { 661 CHECK_NAN(i, log, log_invalid[i]); 662 CHECKL_NAN(i, logl, log_invalid[i]); 663 } 664 665 for (i = 0; i < __arraycount(logl_invalid); i++) { 666 CHECKL_NAN(i, logl, logl_invalid[i]); 667 } 668 } 669 670 ATF_TC(log_zero); 671 ATF_TC_HEAD(log_zero, tc) 672 { 673 atf_tc_set_md_var(tc, "descr", "Test log/f/l on zero"); 674 } 675 ATF_TC_BODY(log_zero, tc) 676 { 677 678 CHECK_EQ(0, logf, +0., -HUGE_VALF); 679 CHECK_EQ(0, log, +0., -HUGE_VAL); 680 CHECKL_EQ(0, logl, +0., -HUGE_VALL); 681 682 CHECK_EQ(1, logf, -0., -HUGE_VALF); 683 CHECK_EQ(1, log, -0., -HUGE_VAL); 684 CHECKL_EQ(1, logl, -0., -HUGE_VALL); 685 } 686 687 ATF_TC(log_exact); 688 ATF_TC_HEAD(log_exact, tc) 689 { 690 atf_tc_set_md_var(tc, "descr", "Test log/f/l exact cases"); 691 } 692 ATF_TC_BODY(log_exact, tc) 693 { 694 695 CHECK_EQ(0, logf, 1, 0); 696 CHECK_EQ(0, log, 1, 0); 697 CHECKL_EQ(0, logl, 1, 0); 698 699 ATF_CHECK_EQ(signbit(logf(1)), 0); 700 ATF_CHECK_EQ(signbit(log(1)), 0); 701 ATF_CHECK_EQ(signbit(logl(1)), 0); 702 } 703 704 ATF_TC(log_approx); 705 ATF_TC_HEAD(log_approx, tc) 706 { 707 atf_tc_set_md_var(tc, "descr", "Test log/f/l approximate cases"); 708 } 709 ATF_TC_BODY(log_approx, tc) 710 { 711 volatile long double e = 712 2.7182818284590452353602874713526624977572470937L; 713 volatile long double e2 = 714 7.3890560989306502272304274605750078131803155705519L; 715 volatile long double log_2 = 716 0.69314718055994530941723212145817656807550013436025L; 717 volatile long double log_10 = 718 2.30258509299404568401799145468436420760110148862875L; 719 720 #if __HAVE_LONG_DOUBLE + 0 == 128 721 atf_tc_expect_fail("PR lib/58337: logl() crashes on arm64"); 722 #endif 723 724 ATF_CHECK_MSG(fabsf((logf(2) - log_2)/log_2) < 2*FLT_EPSILON, 725 "logf(2)=%a=%.8g expected %a=%.8g", 726 logf(2), logf(2), (float)log_2, (float)log_2); 727 ATF_CHECK_MSG(fabs((log(2) - log_2)/log_2) < 2*DBL_EPSILON, 728 "log(2)=%a=%.17g expected %a=%.17g", 729 log(2), log(2), (double)log_2, (double)log_2); 730 ATF_CHECK_MSG(fabsl((logl(2) - log_2)/log_2) < 2*LDBL_EPSILON, 731 "logl(2)=%La=%.34Lg expected %La=%.34Lg", 732 logl(2), logl(2), log_2, log_2); 733 734 ATF_CHECK_MSG(fabsf((logf(e) - 1)/1) < 2*FLT_EPSILON, 735 "logf(e)=%a=%.8g", logf(e), logf(e)); 736 ATF_CHECK_MSG(fabs((log(e) - 1)/1) < 2*DBL_EPSILON, 737 "log(e)=%a=%.17g", log(e), log(e)); 738 ATF_CHECK_MSG(fabsl((logl(e) - 1)/1) < 2*LDBL_EPSILON, 739 "logl(e)=%La=%.34Lg", logl(e), logl(e)); 740 741 ATF_CHECK_MSG(fabsf((logf(e2) - 2)/2) < 2*FLT_EPSILON, 742 "logf(e)=%a=%.8g", logf(e2), logf(e2)); 743 ATF_CHECK_MSG(fabs((log(e2) - 2)/2) < 2*DBL_EPSILON, 744 "log(e)=%a=%.17g", log(e2), log(e2)); 745 ATF_CHECK_MSG(fabsl((logl(e2) - 2)/2) < 2*LDBL_EPSILON, 746 "logl(e)=%La=%.34Lg", logl(e2), logl(e2)); 747 748 ATF_CHECK_MSG(fabsf((logf(10) - log_10)/log_10) < 2*FLT_EPSILON, 749 "logf(10)=%a=%.8g expected %a=%.8g", 750 logf(10), logf(10), (float)log_10, (float)log_10); 751 ATF_CHECK_MSG(fabs((log(10) - log_10)/log_10) < 2*DBL_EPSILON, 752 "log(10)=%a=%.17g expected %a=%.17g", 753 log(10), log(10), (double)log_10, (double)log_10); 754 ATF_CHECK_MSG(fabsl((logl(10) - log_10)/log_10) < 2*LDBL_EPSILON, 755 "logl(10)=%La=%.34Lg expected %La=%.34Lg", 756 logl(10), logl(10), log_10, log_10); 757 } 758 759 ATF_TC(log_inf); 760 ATF_TC_HEAD(log_inf, tc) 761 { 762 atf_tc_set_md_var(tc, "descr", "Test log/f/l on +infinity"); 763 } 764 ATF_TC_BODY(log_inf, tc) 765 { 766 767 if (!isinf(INFINITY)) 768 atf_tc_skip("no infinities on this architecture"); 769 770 CHECK_EQ(0, logf, INFINITY, INFINITY); 771 CHECK_EQ(0, log, INFINITY, INFINITY); 772 CHECKL_EQ(0, logl, INFINITY, INFINITY); 773 } 774 775 ATF_TP_ADD_TCS(tp) 776 { 777 778 ATF_TP_ADD_TC(tp, log10_invalid); 779 ATF_TP_ADD_TC(tp, log10_zero); 780 ATF_TP_ADD_TC(tp, log10_exact); 781 ATF_TP_ADD_TC(tp, log10_approx); 782 ATF_TP_ADD_TC(tp, log10_inf); 783 784 ATF_TP_ADD_TC(tp, log1p_invalid); 785 ATF_TP_ADD_TC(tp, log1p_neg_one); 786 ATF_TP_ADD_TC(tp, log1p_exact); 787 ATF_TP_ADD_TC(tp, log1p_approx); 788 ATF_TP_ADD_TC(tp, log1p_inf); 789 790 ATF_TP_ADD_TC(tp, log2_invalid); 791 ATF_TP_ADD_TC(tp, log2_zero); 792 ATF_TP_ADD_TC(tp, log2_exact); 793 ATF_TP_ADD_TC(tp, log2_approx); 794 ATF_TP_ADD_TC(tp, log2_inf); 795 796 ATF_TP_ADD_TC(tp, log_invalid); 797 ATF_TP_ADD_TC(tp, log_zero); 798 ATF_TP_ADD_TC(tp, log_exact); 799 ATF_TP_ADD_TC(tp, log_approx); 800 ATF_TP_ADD_TC(tp, log_inf); 801 802 return atf_no_error(); 803 } 804