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
TEST_F(LlvmLibcCbrtTest,InDoubleRange)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
TEST_F(LlvmLibcCbrtTest,SpecialValues)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