1 /* $NetBSD: t_log.c,v 1.18 2024/07/17 11:59:58 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.18 2024/07/17 11:59:58 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 for (i = 0; i < __arraycount(log10f_exact); i++) { 242 const float x = log10f_exact[i].x; 243 const float y = log10f_exact[i].y; 244 245 CHECK_EQ(i, log10f, x, y); 246 CHECK_EQ(i, log10, x, y); 247 CHECKL_EQ(i, log10l, x, y); 248 } 249 } 250 251 ATF_TC(log10_approx); 252 ATF_TC_HEAD(log10_approx, tc) 253 { 254 atf_tc_set_md_var(tc, "descr", "Test log10/f/l approximate cases"); 255 } 256 ATF_TC_BODY(log10_approx, tc) 257 { 258 volatile long double e = 259 2.7182818284590452353602874713526624977572470937L; 260 volatile long double e2 = 261 7.3890560989306502272304274605750078131803155705519L; 262 volatile long double log10e = 263 0.43429448190325182765112891891660508229439700580367L; 264 volatile long double log10e2 = 265 2*0.43429448190325182765112891891660508229439700580367L; 266 267 ATF_CHECK_MSG((fabsf((log10f(e) - (float)log10e)/(float)log10e) < 268 2*FLT_EPSILON), 269 "log10f(e)=%a=%.8g expected %a=%.8g", 270 log10f(e), log10f(e), (float)log10e, (float)log10e); 271 ATF_CHECK_MSG((fabs((log10(e) - (double)log10e)/(double)log10e) < 272 2*DBL_EPSILON), 273 "log10(e)=%a=%.17g expected %a=%.17g", 274 log10(e), log10(e), (double)log10e, (double)log10e); 275 ATF_CHECK_MSG((fabsl((log10l(e) - log10e)/log10e) < 2*LDBL_EPSILON), 276 "log10l(e)=%La=%.34Lg expected %La=%.34Lg", 277 log10l(e), log10l(e), log10e, log10e); 278 279 ATF_CHECK_MSG((fabsf((log10f(e2) - (float)log10e2)/(float)log10e2) < 280 2*FLT_EPSILON), 281 "log10f(e^2)=%a=%.8g expected %a=%.8g", 282 log10f(e2), log10f(e2), (float)log10e2, (float)log10e2); 283 ATF_CHECK_MSG((fabs((log10(e2) - (double)log10e2)/(double)log10e2) < 284 2*DBL_EPSILON), 285 "log10(e^2)=%a=%.17g expected %a=%.17g", 286 log10(e2), log10(e2), (double)log10e2, (double)log10e2); 287 ATF_CHECK_MSG((fabsl((log10l(e2) - log10e2)/log10e2) < 2*LDBL_EPSILON), 288 "log10l(e^2)=%La=%.34Lg expected %La=%.34Lg", 289 log10l(e2), log10l(e2), log10e2, log10e2); 290 } 291 292 ATF_TC(log10_inf); 293 ATF_TC_HEAD(log10_inf, tc) 294 { 295 atf_tc_set_md_var(tc, "descr", "Test log10/f/l on +infinity"); 296 } 297 ATF_TC_BODY(log10_inf, tc) 298 { 299 300 if (!isinf(INFINITY)) 301 atf_tc_skip("no infinities on this architecture"); 302 303 CHECK_EQ(0, log10f, INFINITY, INFINITY); 304 CHECK_EQ(0, log10, INFINITY, INFINITY); 305 CHECKL_EQ(0, log10l, INFINITY, INFINITY); 306 } 307 308 /* 309 * log1p(3) 310 */ 311 312 ATF_TC(log1p_invalid); 313 ATF_TC_HEAD(log1p_invalid, tc) 314 { 315 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on invalid inputs"); 316 } 317 ATF_TC_BODY(log1p_invalid, tc) 318 { 319 unsigned i; 320 321 for (i = 0; i < __arraycount(log1pf_invalid); i++) { 322 CHECK_NAN(i, log1pf, log1pf_invalid[i]); 323 CHECK_NAN(i, log1p, log1pf_invalid[i]); 324 CHECKL_NAN(i, log1pl, log1pf_invalid[i]); 325 } 326 327 for (i = 0; i < __arraycount(log1p_invalid); i++) { 328 CHECK_NAN(i, log1p, log1p_invalid[i]); 329 CHECKL_NAN(i, log1pl, log1p_invalid[i]); 330 } 331 332 for (i = 0; i < __arraycount(log1pl_invalid); i++) { 333 CHECKL_NAN(i, log1pl, log1pl_invalid[i]); 334 } 335 } 336 337 ATF_TC(log1p_neg_one); 338 ATF_TC_HEAD(log1p_neg_one, tc) 339 { 340 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on -1"); 341 } 342 ATF_TC_BODY(log1p_neg_one, tc) 343 { 344 345 CHECK_EQ(0, log1pf, -1., -HUGE_VALF); 346 CHECK_EQ(0, log1p, -1., -HUGE_VAL); 347 CHECKL_EQ(0, log1pl, -1., -HUGE_VALL); 348 } 349 350 ATF_TC(log1p_exact); 351 ATF_TC_HEAD(log1p_exact, tc) 352 { 353 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l exact cases"); 354 } 355 ATF_TC_BODY(log1p_exact, tc) 356 { 357 358 CHECK_EQ(0, log1pf, -FLT_MIN, -FLT_MIN); 359 CHECK_EQ(0, log1p, -DBL_MIN, -DBL_MIN); 360 CHECKL_EQ(01, log1pl, -LDBL_MIN, -LDBL_MIN); 361 362 CHECK_EQ(1, log1pf, -0., 0); 363 CHECK_EQ(1, log1p, -0., 0); 364 CHECKL_EQ(1, log1pl, -0., 0); 365 366 CHECK_EQ(2, log1pf, +0., 0); 367 CHECK_EQ(2, log1p, +0., 0); 368 CHECKL_EQ(2, log1pl, +0., 0); 369 370 CHECK_EQ(3, log1pf, 1, logf(2)); 371 CHECK_EQ(3, log1p, 1, log(2)); 372 CHECKL_EQ(3, log1pl, 1, logl(2)); 373 } 374 375 ATF_TC(log1p_approx); 376 ATF_TC_HEAD(log1p_approx, tc) 377 { 378 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l approximate cases"); 379 } 380 ATF_TC_BODY(log1p_approx, tc) 381 { 382 volatile long double em1 = /* exp(1) - 1 */ 383 1.7182818284590452353602874713526624977572470937L; 384 volatile long double e2m1 = /* exp(2) - 1 */ 385 6.3890560989306502272304274605750078131803155705519L; 386 387 /* 388 * Approximation is close enough that equality of the rounded 389 * output had better hold. 390 */ 391 #ifdef FLT_DENORM_MIN 392 CHECK_EQ(0, log1pf, -FLT_DENORM_MIN, -FLT_DENORM_MIN); 393 #endif 394 #ifdef DBL_DENORM_MIN 395 CHECK_EQ(0, log1p, -DBL_DENORM_MIN, -DBL_DENORM_MIN); 396 #endif 397 #ifdef LDBL_DENORM_MIN 398 CHECKL_EQ(0, log1pl, -LDBL_DENORM_MIN, -LDBL_DENORM_MIN); 399 #endif 400 401 ATF_CHECK_MSG(fabsf((log1pf(em1) - 1)/1) < 2*FLT_EPSILON, 402 "log1pf(e)=%a=%.8g", log1pf(em1), log1pf(em1)); 403 ATF_CHECK_MSG(fabs((log1p(em1) - 1)/1) < 2*DBL_EPSILON, 404 "log1p(e)=%a=%.17g", log1p(em1), log1p(em1)); 405 ATF_CHECK_MSG(fabsl((log1pl(em1) - 1)/1) < 2*LDBL_EPSILON, 406 "log1pl(e)=%La=%.34Lg", log1pl(em1), log1pl(em1)); 407 408 ATF_CHECK_MSG(fabsf((log1pf(e2m1) - 2)/2) < 2*FLT_EPSILON, 409 "log1pf(e^2)=%a=%.8g", log1pf(em1), log1pf(em1)); 410 ATF_CHECK_MSG(fabs((log1p(e2m1) - 2)/2) < 2*DBL_EPSILON, 411 "log1p(e^2)=%a=%.17g", log1p(em1), log1p(em1)); 412 ATF_CHECK_MSG(fabsl((log1pl(e2m1) - 2)/2) < 2*LDBL_EPSILON, 413 "log1pl(e^2)=%La=%.34Lg", log1pl(em1), log1pl(em1)); 414 } 415 416 ATF_TC(log1p_inf); 417 ATF_TC_HEAD(log1p_inf, tc) 418 { 419 atf_tc_set_md_var(tc, "descr", "Test log1p/f/l on +infinity"); 420 } 421 ATF_TC_BODY(log1p_inf, tc) 422 { 423 424 if (!isinf(INFINITY)) 425 atf_tc_skip("no infinities on this architecture"); 426 427 CHECK_EQ(0, log1pf, INFINITY, INFINITY); 428 CHECK_EQ(0, log1p, INFINITY, INFINITY); 429 CHECKL_EQ(0, log1pl, INFINITY, INFINITY); 430 } 431 432 /* 433 * log2(3) 434 */ 435 static const struct { 436 float x, y; 437 } log2f_exact[] = { 438 #ifdef FLT_DENORM_MIN 439 { FLT_DENORM_MIN, FLT_MIN_EXP - FLT_MANT_DIG }, 440 #endif 441 { FLT_MIN, FLT_MIN_EXP - 1 }, 442 { 0.25, -2 }, 443 { 0.5, -1 }, 444 { 1, 0 }, 445 { 2, 1 }, 446 { 4, 2 }, 447 { 8, 3 }, 448 { 1 << FLT_MANT_DIG, FLT_MANT_DIG }, 449 { (float)(1 << FLT_MANT_DIG) * (1 << FLT_MANT_DIG), 450 2*FLT_MANT_DIG }, 451 }; 452 static const struct { 453 double x, y; 454 } log2_exact[] = { 455 #ifdef DBL_DENORM_MIN 456 { DBL_DENORM_MIN, DBL_MIN_EXP - DBL_MANT_DIG }, 457 #endif 458 { DBL_MIN, DBL_MIN_EXP - 1 }, 459 { (uint64_t)1 << DBL_MANT_DIG, DBL_MANT_DIG }, 460 { ((double)((uint64_t)1 << DBL_MANT_DIG) * 461 ((uint64_t)1 << DBL_MANT_DIG)), 462 2*DBL_MANT_DIG }, 463 }; 464 465 static const struct { 466 long double x, y; 467 } log2l_exact[] = { 468 #ifdef LDBL_DENORM_MIN 469 { LDBL_DENORM_MIN, LDBL_MIN_EXP - LDBL_MANT_DIG }, 470 #endif 471 { LDBL_MIN, LDBL_MIN_EXP - 1 }, 472 { ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) * 473 ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))), 474 LDBL_MANT_DIG }, 475 { (((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) * 476 ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2))) * 477 ((long double)((uint64_t)1 << (LDBL_MANT_DIG/2)) * 478 ((uint64_t)1 << ((LDBL_MANT_DIG + 1)/2)))), 479 2*LDBL_MANT_DIG }, 480 }; 481 482 ATF_TC(log2_invalid); 483 ATF_TC_HEAD(log2_invalid, tc) 484 { 485 atf_tc_set_md_var(tc, "descr", "Test log2/f/l on invalid inputs"); 486 } 487 ATF_TC_BODY(log2_invalid, tc) 488 { 489 unsigned i; 490 491 for (i = 0; i < __arraycount(logf_invalid); i++) { 492 CHECK_NAN(i, log2f, logf_invalid[i]); 493 CHECK_NAN(i, log2, logf_invalid[i]); 494 CHECKL_NAN(i, log2l, logf_invalid[i]); 495 } 496 497 for (i = 0; i < __arraycount(log_invalid); i++) { 498 CHECK_NAN(i, log2, log_invalid[i]); 499 CHECKL_NAN(i, log2l, log_invalid[i]); 500 } 501 502 for (i = 0; i < __arraycount(logl_invalid); i++) { 503 CHECKL_NAN(i, log2l, logl_invalid[i]); 504 } 505 } 506 507 ATF_TC(log2_zero); 508 ATF_TC_HEAD(log2_zero, tc) 509 { 510 atf_tc_set_md_var(tc, "descr", "Test log2/f/l on zero"); 511 } 512 ATF_TC_BODY(log2_zero, tc) 513 { 514 515 CHECK_EQ(0, log2f, +0., -HUGE_VALF); 516 CHECK_EQ(0, log2, +0., -HUGE_VAL); 517 CHECKL_EQ(0, log2l, +0., -HUGE_VALL); 518 519 CHECK_EQ(1, log2f, -0., -HUGE_VALF); 520 CHECK_EQ(1, log2, -0., -HUGE_VAL); 521 CHECKL_EQ(1, log2l, -0., -HUGE_VALL); 522 } 523 524 ATF_TC(log2_exact); 525 ATF_TC_HEAD(log2_exact, tc) 526 { 527 atf_tc_set_md_var(tc, "descr", "Test log2/f/l exact cases"); 528 } 529 ATF_TC_BODY(log2_exact, tc) 530 { 531 unsigned i; 532 533 ATF_CHECK_EQ(signbit(log2f(1)), 0); 534 ATF_CHECK_EQ(signbit(log2(1)), 0); 535 ATF_CHECK_EQ(signbit(log2l(1)), 0); 536 537 for (i = 0; i < __arraycount(log2f_exact); i++) { 538 const float x = log2f_exact[i].x; 539 const float y = log2f_exact[i].y; 540 541 CHECK_EQ(i, log2f, x, y); 542 CHECK_EQ(i, log2, x, y); 543 CHECKL_EQ(i, log2l, x, y); 544 } 545 546 for (i = 0; i < __arraycount(log2_exact); i++) { 547 const double x = log2_exact[i].x; 548 const double y = log2_exact[i].y; 549 550 CHECK_EQ(i, log2, x, y); 551 CHECKL_EQ(i, log2l, x, y); 552 } 553 554 for (i = 0; i < __arraycount(log2l_exact); i++) { 555 const long double x = log2l_exact[i].x; 556 const long double y = log2l_exact[i].y; 557 558 CHECKL_EQ(i, log2l, x, y); 559 } 560 } 561 562 ATF_TC(log2_approx); 563 ATF_TC_HEAD(log2_approx, tc) 564 { 565 atf_tc_set_md_var(tc, "descr", "Test log2/f/l approximate cases"); 566 } 567 ATF_TC_BODY(log2_approx, tc) 568 { 569 volatile long double e = 570 2.7182818284590452353602874713526624977572470937L; 571 volatile long double e2 = 572 7.3890560989306502272304274605750078131803155705519L; 573 volatile long double log2e = 574 1.442695040888963407359924681001892137426645954153L; 575 volatile long double log2e2 = 576 2*1.442695040888963407359924681001892137426645954153L; 577 578 ATF_CHECK_MSG((fabsf((log2f(e) - (float)log2e)/(float)log2e) < 579 2*FLT_EPSILON), 580 "log2f(e)=%a=%.8g expected %a=%.8g", 581 log2f(e), log2f(e), (float)log2e, (float)log2e); 582 ATF_CHECK_MSG((fabs((log2(e) - (double)log2e)/(double)log2e) < 583 2*DBL_EPSILON), 584 "log2(e)=%a=%.17g expected %a=%.17g", 585 log2(e), log2(e), (double)log2e, (double)log2e); 586 ATF_CHECK_MSG((fabsl((log2l(e) - log2e)/log2e) < 2*LDBL_EPSILON), 587 "log2l(e)=%La=%.34Lg expected %La=%.34Lg", 588 log2l(e), log2l(e), log2e, log2e); 589 590 ATF_CHECK_MSG((fabsf((log2f(e2) - (float)log2e2)/(float)log2e2) < 591 2*FLT_EPSILON), 592 "log2f(e^2)=%a=%.8g expected %a=%.8g", 593 log2f(e2), log2f(e2), (float)log2e2, (float)log2e2); 594 ATF_CHECK_MSG((fabs((log2(e2) - (double)log2e2)/(double)log2e2) < 595 2*DBL_EPSILON), 596 "log2(e^2)=%a=%.17g expected %a=%.17g", 597 log2(e2), log2(e2), (double)log2e2, (double)log2e2); 598 ATF_CHECK_MSG((fabsl((log2l(e2) - log2e2)/log2e2) < 2*LDBL_EPSILON), 599 "log2l(e^2)=%La=%.34Lg expected %La=%.34Lg", 600 log2l(e2), log2l(e2), log2e2, log2e2); 601 } 602 603 ATF_TC(log2_inf); 604 ATF_TC_HEAD(log2_inf, tc) 605 { 606 atf_tc_set_md_var(tc, "descr", "Test log2/f/l on +infinity"); 607 } 608 ATF_TC_BODY(log2_inf, tc) 609 { 610 611 if (!isinf(INFINITY)) 612 atf_tc_skip("no infinities on this architecture"); 613 614 CHECK_EQ(0, log2f, INFINITY, INFINITY); 615 CHECK_EQ(0, log2, INFINITY, INFINITY); 616 CHECKL_EQ(0, log2l, INFINITY, INFINITY); 617 } 618 619 /* 620 * log(3) 621 */ 622 623 ATF_TC(log_invalid); 624 ATF_TC_HEAD(log_invalid, tc) 625 { 626 atf_tc_set_md_var(tc, "descr", "Test log/f/l on invalid inputs"); 627 } 628 ATF_TC_BODY(log_invalid, tc) 629 { 630 unsigned i; 631 632 for (i = 0; i < __arraycount(logf_invalid); i++) { 633 CHECK_NAN(i, logf, logf_invalid[i]); 634 CHECK_NAN(i, log, logf_invalid[i]); 635 CHECKL_NAN(i, logl, logf_invalid[i]); 636 } 637 638 for (i = 0; i < __arraycount(log_invalid); i++) { 639 CHECK_NAN(i, log, log_invalid[i]); 640 CHECKL_NAN(i, logl, log_invalid[i]); 641 } 642 643 for (i = 0; i < __arraycount(logl_invalid); i++) { 644 CHECKL_NAN(i, logl, logl_invalid[i]); 645 } 646 } 647 648 ATF_TC(log_zero); 649 ATF_TC_HEAD(log_zero, tc) 650 { 651 atf_tc_set_md_var(tc, "descr", "Test log/f/l on zero"); 652 } 653 ATF_TC_BODY(log_zero, tc) 654 { 655 656 CHECK_EQ(0, logf, +0., -HUGE_VALF); 657 CHECK_EQ(0, log, +0., -HUGE_VAL); 658 CHECKL_EQ(0, logl, +0., -HUGE_VALL); 659 660 CHECK_EQ(1, logf, -0., -HUGE_VALF); 661 CHECK_EQ(1, log, -0., -HUGE_VAL); 662 CHECKL_EQ(1, logl, -0., -HUGE_VALL); 663 } 664 665 ATF_TC(log_exact); 666 ATF_TC_HEAD(log_exact, tc) 667 { 668 atf_tc_set_md_var(tc, "descr", "Test log/f/l exact cases"); 669 } 670 ATF_TC_BODY(log_exact, tc) 671 { 672 673 CHECK_EQ(0, logf, 1, 0); 674 CHECK_EQ(0, log, 1, 0); 675 CHECKL_EQ(0, logl, 1, 0); 676 677 ATF_CHECK_EQ(signbit(logf(1)), 0); 678 ATF_CHECK_EQ(signbit(log(1)), 0); 679 ATF_CHECK_EQ(signbit(logl(1)), 0); 680 } 681 682 ATF_TC(log_approx); 683 ATF_TC_HEAD(log_approx, tc) 684 { 685 atf_tc_set_md_var(tc, "descr", "Test log/f/l approximate cases"); 686 } 687 ATF_TC_BODY(log_approx, tc) 688 { 689 volatile long double e = 690 2.7182818284590452353602874713526624977572470937L; 691 volatile long double e2 = 692 7.3890560989306502272304274605750078131803155705519L; 693 volatile long double log_2 = 694 0.69314718055994530941723212145817656807550013436025L; 695 volatile long double log_10 = 696 2.30258509299404568401799145468436420760110148862875L; 697 698 ATF_CHECK_MSG(fabsf((logf(2) - log_2)/log_2) < 2*FLT_EPSILON, 699 "logf(2)=%a=%.8g expected %a=%.8g", 700 logf(2), logf(2), (float)log_2, (float)log_2); 701 ATF_CHECK_MSG(fabs((log(2) - log_2)/log_2) < 2*DBL_EPSILON, 702 "log(2)=%a=%.17g expected %a=%.17g", 703 log(2), log(2), (double)log_2, (double)log_2); 704 ATF_CHECK_MSG(fabsl((logl(2) - log_2)/log_2) < 2*LDBL_EPSILON, 705 "logl(2)=%La=%.34Lg expected %La=%.34Lg", 706 logl(2), logl(2), log_2, log_2); 707 708 ATF_CHECK_MSG(fabsf((logf(e) - 1)/1) < 2*FLT_EPSILON, 709 "logf(e)=%a=%.8g", logf(e), logf(e)); 710 ATF_CHECK_MSG(fabs((log(e) - 1)/1) < 2*DBL_EPSILON, 711 "log(e)=%a=%.17g", log(e), log(e)); 712 ATF_CHECK_MSG(fabsl((logl(e) - 1)/1) < 2*LDBL_EPSILON, 713 "logl(e)=%La=%.34Lg", logl(e), logl(e)); 714 715 ATF_CHECK_MSG(fabsf((logf(e2) - 2)/2) < 2*FLT_EPSILON, 716 "logf(e)=%a=%.8g", logf(e2), logf(e2)); 717 ATF_CHECK_MSG(fabs((log(e2) - 2)/2) < 2*DBL_EPSILON, 718 "log(e)=%a=%.17g", log(e2), log(e2)); 719 ATF_CHECK_MSG(fabsl((logl(e2) - 2)/2) < 2*LDBL_EPSILON, 720 "logl(e)=%La=%.34Lg", logl(e2), logl(e2)); 721 722 ATF_CHECK_MSG(fabsf((logf(10) - log_10)/log_10) < 2*FLT_EPSILON, 723 "logf(10)=%a=%.8g expected %a=%.8g", 724 logf(10), logf(10), (float)log_10, (float)log_10); 725 ATF_CHECK_MSG(fabs((log(10) - log_10)/log_10) < 2*DBL_EPSILON, 726 "log(10)=%a=%.17g expected %a=%.17g", 727 log(10), log(10), (double)log_10, (double)log_10); 728 ATF_CHECK_MSG(fabsl((logl(10) - log_10)/log_10) < 2*LDBL_EPSILON, 729 "logl(10)=%La=%.34Lg expected %La=%.34Lg", 730 logl(10), logl(10), log_10, log_10); 731 } 732 733 ATF_TC(log_inf); 734 ATF_TC_HEAD(log_inf, tc) 735 { 736 atf_tc_set_md_var(tc, "descr", "Test log/f/l on +infinity"); 737 } 738 ATF_TC_BODY(log_inf, tc) 739 { 740 741 if (!isinf(INFINITY)) 742 atf_tc_skip("no infinities on this architecture"); 743 744 CHECK_EQ(0, logf, INFINITY, INFINITY); 745 CHECK_EQ(0, log, INFINITY, INFINITY); 746 CHECKL_EQ(0, logl, INFINITY, INFINITY); 747 } 748 749 ATF_TP_ADD_TCS(tp) 750 { 751 752 ATF_TP_ADD_TC(tp, log10_invalid); 753 ATF_TP_ADD_TC(tp, log10_zero); 754 ATF_TP_ADD_TC(tp, log10_exact); 755 ATF_TP_ADD_TC(tp, log10_approx); 756 ATF_TP_ADD_TC(tp, log10_inf); 757 758 ATF_TP_ADD_TC(tp, log1p_invalid); 759 ATF_TP_ADD_TC(tp, log1p_neg_one); 760 ATF_TP_ADD_TC(tp, log1p_exact); 761 ATF_TP_ADD_TC(tp, log1p_approx); 762 ATF_TP_ADD_TC(tp, log1p_inf); 763 764 ATF_TP_ADD_TC(tp, log2_invalid); 765 ATF_TP_ADD_TC(tp, log2_zero); 766 ATF_TP_ADD_TC(tp, log2_exact); 767 ATF_TP_ADD_TC(tp, log2_approx); 768 ATF_TP_ADD_TC(tp, log2_inf); 769 770 ATF_TP_ADD_TC(tp, log_invalid); 771 ATF_TP_ADD_TC(tp, log_zero); 772 ATF_TP_ADD_TC(tp, log_exact); 773 ATF_TP_ADD_TC(tp, log_approx); 774 ATF_TP_ADD_TC(tp, log_inf); 775 776 return atf_no_error(); 777 } 778