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