15814b7b2STue Ly //===-- Unittests for log10 -----------------------------------------------===// 25814b7b2STue Ly // 35814b7b2STue Ly // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45814b7b2STue Ly // See https://llvm.org/LICENSE.txt for license information. 55814b7b2STue Ly // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65814b7b2STue Ly // 75814b7b2STue Ly //===----------------------------------------------------------------------===// 85814b7b2STue Ly 95748ad84Slntue #include "hdr/math_macros.h" 105814b7b2STue Ly #include "src/__support/FPUtil/FPBits.h" 1131c39439STue Ly #include "src/errno/libc_errno.h" 125814b7b2STue Ly #include "src/math/log10.h" 13af1315c2SSiva Chandra Reddy #include "test/UnitTest/FPMatcher.h" 14af1315c2SSiva Chandra Reddy #include "test/UnitTest/Test.h" 155814b7b2STue Ly #include "utils/MPFRWrapper/MPFRUtils.h" 165814b7b2STue Ly 175814b7b2STue Ly #include <stdint.h> 185814b7b2STue Ly 193fd5113cSlntue using LlvmLibcLog10Test = LIBC_NAMESPACE::testing::FPTest<double>; 203fd5113cSlntue 21b6bc9d72SGuillaume Chatelet namespace mpfr = LIBC_NAMESPACE::testing::mpfr; 22b6bc9d72SGuillaume Chatelet using LIBC_NAMESPACE::testing::tlog; 235814b7b2STue Ly 243fd5113cSlntue TEST_F(LlvmLibcLog10Test, SpecialNumbers) { 25b6bc9d72SGuillaume Chatelet EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::log10(aNaN)); 26b6bc9d72SGuillaume Chatelet EXPECT_FP_EQ(inf, LIBC_NAMESPACE::log10(inf)); 27b6bc9d72SGuillaume Chatelet EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log10(neg_inf), FE_INVALID); 28b6bc9d72SGuillaume Chatelet EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, LIBC_NAMESPACE::log10(0.0), 29b6bc9d72SGuillaume Chatelet FE_DIVBYZERO); 30b6bc9d72SGuillaume Chatelet EXPECT_FP_EQ_WITH_EXCEPTION(neg_inf, LIBC_NAMESPACE::log10(-0.0), 31b6bc9d72SGuillaume Chatelet FE_DIVBYZERO); 32b6bc9d72SGuillaume Chatelet EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::log10(-1.0), FE_INVALID); 33b6bc9d72SGuillaume Chatelet EXPECT_FP_EQ_ALL_ROUNDING(zero, LIBC_NAMESPACE::log10(1.0)); 345814b7b2STue Ly } 355814b7b2STue Ly 363fd5113cSlntue TEST_F(LlvmLibcLog10Test, TrickyInputs) { 37434bf160STue Ly constexpr int N = 36; 3872a794c2STue Ly constexpr uint64_t INPUTS[N] = { 3972a794c2STue Ly 0x3ff0000000000000, // x = 1.0 4072a794c2STue Ly 0x4024000000000000, // x = 10.0 4172a794c2STue Ly 0x4059000000000000, // x = 10^2 4272a794c2STue Ly 0x408f400000000000, // x = 10^3 4372a794c2STue Ly 0x40c3880000000000, // x = 10^4 4472a794c2STue Ly 0x40f86a0000000000, // x = 10^5 4572a794c2STue Ly 0x412e848000000000, // x = 10^6 4672a794c2STue Ly 0x416312d000000000, // x = 10^7 4772a794c2STue Ly 0x4197d78400000000, // x = 10^8 4872a794c2STue Ly 0x41cdcd6500000000, // x = 10^9 4972a794c2STue Ly 0x4202a05f20000000, // x = 10^10 5072a794c2STue Ly 0x42374876e8000000, // x = 10^11 5172a794c2STue Ly 0x426d1a94a2000000, // x = 10^12 5272a794c2STue Ly 0x42a2309ce5400000, // x = 10^13 5372a794c2STue Ly 0x42d6bcc41e900000, // x = 10^14 5472a794c2STue Ly 0x430c6bf526340000, // x = 10^15 5572a794c2STue Ly 0x4341c37937e08000, // x = 10^16 5672a794c2STue Ly 0x4376345785d8a000, // x = 10^17 5772a794c2STue Ly 0x43abc16d674ec800, // x = 10^18 5872a794c2STue Ly 0x43e158e460913d00, // x = 10^19 5972a794c2STue Ly 0x4415af1d78b58c40, // x = 10^20 6072a794c2STue Ly 0x444b1ae4d6e2ef50, // x = 10^21 6172a794c2STue Ly 0x4480f0cf064dd592, // x = 10^22 62a0c92a38STue Ly 0x3fefffffffef06ad, 0x3fefde0f22c7d0eb, 0x225e7812faadb32f, 63a0c92a38STue Ly 0x3fee1076964c2903, 0x3fdfe93fff7fceb0, 0x3ff012631ad8df10, 64a0c92a38STue Ly 0x3fefbfdaa448ed98, 0x44b0c9705a25ce02, 0x2c88d301065c7f9b, 65434bf160STue Ly 0x30160580e7268a99, 0x5ca04103b7eaa345, 0x19ad77dc4a40093f, 66434bf160STue Ly 0x0000449fb5c8a96e}; 6772a794c2STue Ly for (int i = 0; i < N; ++i) { 682856db0dSGuillaume Chatelet double x = FPBits(INPUTS[i]).get_val(); 6972a794c2STue Ly EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x, 70b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::log10(x), 0.5); 7172a794c2STue Ly } 7272a794c2STue Ly } 735814b7b2STue Ly 743fd5113cSlntue TEST_F(LlvmLibcLog10Test, AllExponents) { 75a0c92a38STue Ly double x = 0x1.0p-1074; 76a0c92a38STue Ly for (int i = -1074; i < 1024; ++i, x *= 2.0) { 77a0c92a38STue Ly ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Log10, x, 78b6bc9d72SGuillaume Chatelet LIBC_NAMESPACE::log10(x), 0.5); 79a0c92a38STue Ly } 80a0c92a38STue Ly } 81a0c92a38STue Ly 823fd5113cSlntue TEST_F(LlvmLibcLog10Test, InDoubleRange) { 832697ffd0SGuillaume Chatelet constexpr uint64_t COUNT = 1'001; 84a0c92a38STue Ly constexpr uint64_t START = 0x3FD0'0000'0000'0000ULL; // 0.25 85a0c92a38STue Ly constexpr uint64_t STOP = 0x4010'0000'0000'0000ULL; // 4.0 86a0c92a38STue Ly // constexpr uint64_t START = 0x3FF0'0000'0000'0000ULL; // 1.0 87a0c92a38STue Ly // constexpr uint64_t STOP = 0x4000'0000'0000'0000ULL; // 2.0 88a0c92a38STue Ly constexpr uint64_t STEP = (STOP - START) / COUNT; 895814b7b2STue Ly 9072a794c2STue Ly auto test = [&](mpfr::RoundingMode rounding_mode) { 9172a794c2STue Ly mpfr::ForceRoundingMode __r(rounding_mode); 92055be3c3STue Ly if (!__r.success) 93055be3c3STue Ly return; 9472a794c2STue Ly uint64_t fails = 0; 9572a794c2STue Ly uint64_t count = 0; 9672a794c2STue Ly uint64_t cc = 0; 9772a794c2STue Ly double mx, mr = 0.0; 9872a794c2STue Ly double tol = 0.5; 995814b7b2STue Ly 100a0c92a38STue Ly for (uint64_t i = 0, v = START; i <= COUNT; ++i, v += STEP) { 10172a794c2STue Ly double x = FPBits(v).get_val(); 102*f8f5b175SNhat Nguyen if (FPBits(v).is_nan() || FPBits(v).is_inf() || x < 0.0) 10372a794c2STue Ly continue; 1043eb1e6d8Smichaelrj-google LIBC_NAMESPACE::libc_errno = 0; 105b6bc9d72SGuillaume Chatelet double result = LIBC_NAMESPACE::log10(x); 10672a794c2STue Ly ++cc; 107*f8f5b175SNhat Nguyen if (FPBits(result).is_nan() || FPBits(result).is_inf()) 10872a794c2STue Ly continue; 1095814b7b2STue Ly 11072a794c2STue Ly ++count; 11172a794c2STue Ly // ASSERT_MPFR_MATCH(mpfr::Operation::Log10, x, result, 0.5); 1129902fc8dSGuillaume Chatelet if (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(mpfr::Operation::Log10, x, result, 1139902fc8dSGuillaume Chatelet 0.5, rounding_mode)) { 11472a794c2STue Ly ++fails; 1159902fc8dSGuillaume Chatelet while (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(mpfr::Operation::Log10, x, 1169902fc8dSGuillaume Chatelet result, tol, rounding_mode)) { 11772a794c2STue Ly mx = x; 11872a794c2STue Ly mr = result; 11972a794c2STue Ly tol *= 2.0; 12072a794c2STue Ly } 12172a794c2STue Ly } 12272a794c2STue Ly } 123a0c92a38STue Ly tlog << " Log10 failed: " << fails << "/" << count << "/" << cc 124a0c92a38STue Ly << " tests.\n"; 125a0c92a38STue Ly tlog << " Max ULPs is at most: " << static_cast<uint64_t>(tol) << ".\n"; 12672a794c2STue Ly if (fails) { 12772a794c2STue Ly EXPECT_MPFR_MATCH(mpfr::Operation::Log10, mx, mr, 0.5, rounding_mode); 12872a794c2STue Ly } 12972a794c2STue Ly }; 1305814b7b2STue Ly 131a0c92a38STue Ly tlog << " Test Rounding To Nearest...\n"; 13272a794c2STue Ly test(mpfr::RoundingMode::Nearest); 1335814b7b2STue Ly 134a0c92a38STue Ly tlog << " Test Rounding Downward...\n"; 13572a794c2STue Ly test(mpfr::RoundingMode::Downward); 1365814b7b2STue Ly 137a0c92a38STue Ly tlog << " Test Rounding Upward...\n"; 13872a794c2STue Ly test(mpfr::RoundingMode::Upward); 1395814b7b2STue Ly 140a0c92a38STue Ly tlog << " Test Rounding Toward Zero...\n"; 14172a794c2STue Ly test(mpfr::RoundingMode::TowardZero); 14272a794c2STue Ly } 143