xref: /aosp_15_r20/external/llvm-libc/test/src/math/cbrt_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
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