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
19namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
20
21template <typename T, bool InverseMultiplication>
22class 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
44public:
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(x: 2.0, exp: 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(x: 2.0, exp: 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
70using LlvmLibcFModFloatTest = LlvmLibcFModTest<float, false>;
71TEST_F(LlvmLibcFModFloatTest, ExtensiveTest) { testExtensive(); }
72
73using LlvmLibcFModFloatInvTest = LlvmLibcFModTest<float, true>;
74TEST_F(LlvmLibcFModFloatInvTest, ExtensiveTest) { testExtensive(); }
75
76using LlvmLibcFModDoubleTest = LlvmLibcFModTest<double, false>;
77TEST_F(LlvmLibcFModDoubleTest, ExtensiveTest) { testExtensive(); }
78
79using LlvmLibcFModDoubleInvTest = LlvmLibcFModTest<double, true>;
80TEST_F(LlvmLibcFModDoubleInvTest, ExtensiveTest) { testExtensive(); }
81

source code of libc/test/src/math/exhaustive/fmod_generic_impl_test.cpp