xref: /aosp_15_r20/external/llvm-libc/test/src/math/exhaustive/fmod_generic_impl_test.cpp (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Utility class to test FMod generic implementation -------*- C++ -*-===//
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 #include "src/__support/CPP/type_traits.h"
9 #include "src/__support/FPUtil/FPBits.h"
10 #include "src/__support/FPUtil/ManipulationFunctions.h" // ldexp
11 #include "src/__support/FPUtil/generic/FMod.h"
12 #include "test/UnitTest/FEnvSafeTest.h"
13 #include "test/UnitTest/FPMatcher.h"
14 #include "test/UnitTest/Test.h"
15 #include "utils/MPFRWrapper/MPFRUtils.h"
16 
17 #include <array>
18 
19 namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
20 
21 template <typename T, bool InverseMultiplication>
22 class LlvmLibcFModTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
23 
24   using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
25   using U = typename FPBits::StorageType;
26   using DivisionHelper = LIBC_NAMESPACE::cpp::conditional_t<
27       InverseMultiplication,
28       LIBC_NAMESPACE::fputil::generic::FModDivisionInvMultHelper<U>,
29       LIBC_NAMESPACE::fputil::generic::FModDivisionSimpleHelper<U>>;
30 
31   static constexpr std::array<T, 11> TEST_BASES = {
32       T(0.0),
33       T(1.0),
34       T(3.0),
35       T(27.0),
36       T(11.0 / 8.0),
37       T(2.764443),
38       T(1.0) - T(0x1.0p-23) - T(0x1.0p-52) - T(0x1.0p-112),
39       T(1.0) + T(0x1.0p-23) + T(0x1.0p-52) + T(0x1.0p-112),
40       T(3.14159265),
41       T(1.41421356),
42       T(2.71828183)};
43 
44 public:
testExtensive()45   void testExtensive() {
46     using FMod = LIBC_NAMESPACE::fputil::generic::FMod<T, U, DivisionHelper>;
47     int min2 = -(FPBits::MAX_BIASED_EXPONENT + FPBits::SIG_LEN) / 2;
48     int max2 = 3 + FPBits::MAX_BIASED_EXPONENT / 2;
49     for (T by : TEST_BASES) {
50       for (int iy = min2; iy < max2; iy++) {
51         T y = by * LIBC_NAMESPACE::fputil::ldexp(2.0, iy);
52         FPBits y_bits(y);
53         if (y_bits.is_zero() || !y_bits.is_finite())
54           continue;
55         for (T bx : TEST_BASES) {
56           for (int ix = min2; ix < max2; ix++) {
57             T x = bx * LIBC_NAMESPACE::fputil::ldexp(2.0, ix);
58             if (!FPBits(x).is_finite())
59               continue;
60             T result = FMod::eval(x, y);
61             mpfr::BinaryInput<T> input{x, y};
62             EXPECT_MPFR_MATCH(mpfr::Operation::Fmod, input, result, 0.0);
63           }
64         }
65       }
66     }
67   }
68 };
69 
70 using LlvmLibcFModFloatTest = LlvmLibcFModTest<float, false>;
TEST_F(LlvmLibcFModFloatTest,ExtensiveTest)71 TEST_F(LlvmLibcFModFloatTest, ExtensiveTest) { testExtensive(); }
72 
73 using LlvmLibcFModFloatInvTest = LlvmLibcFModTest<float, true>;
TEST_F(LlvmLibcFModFloatInvTest,ExtensiveTest)74 TEST_F(LlvmLibcFModFloatInvTest, ExtensiveTest) { testExtensive(); }
75 
76 using LlvmLibcFModDoubleTest = LlvmLibcFModTest<double, false>;
TEST_F(LlvmLibcFModDoubleTest,ExtensiveTest)77 TEST_F(LlvmLibcFModDoubleTest, ExtensiveTest) { testExtensive(); }
78 
79 using LlvmLibcFModDoubleInvTest = LlvmLibcFModTest<double, true>;
TEST_F(LlvmLibcFModDoubleInvTest,ExtensiveTest)80 TEST_F(LlvmLibcFModDoubleInvTest, ExtensiveTest) { testExtensive(); }
81