1 //===-- Unittests for cbrt ------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "hdr/math_macros.h" 10 #include "src/__support/FPUtil/FPBits.h" 11 #include "src/math/cbrt.h" 12 #include "test/UnitTest/FPMatcher.h" 13 #include "test/UnitTest/Test.h" 14 #include "utils/MPFRWrapper/MPFRUtils.h" 15 16 using LlvmLibcCbrtTest = LIBC_NAMESPACE::testing::FPTest<double>; 17 18 namespace mpfr = LIBC_NAMESPACE::testing::mpfr; 19 20 using LIBC_NAMESPACE::testing::tlog; 21 22 TEST_F(LlvmLibcCbrtTest, InDoubleRange) { 23 constexpr uint64_t COUNT = 123'451; 24 uint64_t START = FPBits(1.0).uintval(); 25 uint64_t STOP = FPBits(8.0).uintval(); 26 uint64_t STEP = (STOP - START) / COUNT; 27 28 auto test = [&](mpfr::RoundingMode rounding_mode) { 29 mpfr::ForceRoundingMode force_rounding(rounding_mode); 30 if (!force_rounding.success) 31 return; 32 33 uint64_t fails = 0; 34 uint64_t tested = 0; 35 uint64_t total = 0; 36 double worst_input, worst_output = 0.0; 37 double ulp = 0.5; 38 39 for (uint64_t i = 0, v = START; i <= COUNT; ++i, v += STEP) { 40 double x = FPBits(v).get_val(); 41 if (FPBits(x).is_inf_or_nan()) 42 continue; 43 44 double result = LIBC_NAMESPACE::cbrt(x); 45 ++total; 46 if (FPBits(result).is_inf_or_nan()) 47 continue; 48 49 ++tested; 50 51 if (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(mpfr::Operation::Cbrt, x, result, 52 0.5, rounding_mode)) { 53 ++fails; 54 while (!TEST_MPFR_MATCH_ROUNDING_SILENTLY(mpfr::Operation::Cbrt, x, 55 result, ulp, rounding_mode)) { 56 worst_input = x; 57 worst_output = result; 58 59 if (ulp > 1000.0) 60 break; 61 62 ulp *= 2.0; 63 } 64 } 65 } 66 if (fails) { 67 tlog << " Cbrt failed: " << fails << "/" << tested << "/" << total 68 << " tests.\n"; 69 tlog << " Max ULPs is at most: " << static_cast<uint64_t>(ulp) << ".\n"; 70 EXPECT_MPFR_MATCH(mpfr::Operation::Cbrt, worst_input, worst_output, 0.5, 71 rounding_mode); 72 } 73 }; 74 75 tlog << " Test Rounding To Nearest...\n"; 76 test(mpfr::RoundingMode::Nearest); 77 78 tlog << " Test Rounding Downward...\n"; 79 test(mpfr::RoundingMode::Downward); 80 81 tlog << " Test Rounding Upward...\n"; 82 test(mpfr::RoundingMode::Upward); 83 84 tlog << " Test Rounding Toward Zero...\n"; 85 test(mpfr::RoundingMode::TowardZero); 86 } 87 88 TEST_F(LlvmLibcCbrtTest, SpecialValues) { 89 constexpr double INPUTS[] = { 90 0x1.4f61672324c8p-1028, -0x1.fffffffffffffp-1021, 0x1.00152f57068b7p-1, 91 0x1.006509cda9886p-1, 0x1.018369b92e523p-1, 0x1.10af932ef2bf9p-1, 92 0x1.1a41117939fdbp-1, 0x1.2ae8076520d9ap-1, 0x1.a202bfc89ddffp-1, 93 0x1.a6bb8c803147bp-1, 0x1.000197b499b1bp+0, 0x1.00065ed266c6cp+0, 94 0x1.d4306c202c4c2p+0, 0x1.8fd409efe4851p+1, 0x1.95fd0eb31cc4p+1, 95 0x1.7cef1d276e335p+2, 0x1.94910c4fc98p+2, 0x1.a0cc1327bb4c4p+2, 96 0x1.e7d6ebed549c4p+2, 97 }; 98 for (double v : INPUTS) { 99 double x = FPBits(v).get_val(); 100 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cbrt, x, 101 LIBC_NAMESPACE::cbrt(x), 0.5); 102 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cbrt, -x, 103 LIBC_NAMESPACE::cbrt(-x), 0.5); 104 } 105 } 106