//===-- Utility class to test FMod generic implementation -------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "src/__support/CPP/type_traits.h" #include "src/__support/FPUtil/FPBits.h" #include "src/__support/FPUtil/ManipulationFunctions.h" // ldexp #include "src/__support/FPUtil/generic/FMod.h" #include "test/UnitTest/FEnvSafeTest.h" #include "test/UnitTest/FPMatcher.h" #include "test/UnitTest/Test.h" #include "utils/MPFRWrapper/MPFRUtils.h" #include namespace mpfr = LIBC_NAMESPACE::testing::mpfr; template class LlvmLibcFModTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using U = typename FPBits::StorageType; using DivisionHelper = LIBC_NAMESPACE::cpp::conditional_t< InverseMultiplication, LIBC_NAMESPACE::fputil::generic::FModDivisionInvMultHelper, LIBC_NAMESPACE::fputil::generic::FModDivisionSimpleHelper>; static constexpr std::array TEST_BASES = { T(0.0), T(1.0), T(3.0), T(27.0), T(11.0 / 8.0), T(2.764443), T(1.0) - T(0x1.0p-23) - T(0x1.0p-52) - T(0x1.0p-112), T(1.0) + T(0x1.0p-23) + T(0x1.0p-52) + T(0x1.0p-112), T(3.14159265), T(1.41421356), T(2.71828183)}; public: void testExtensive() { using FMod = LIBC_NAMESPACE::fputil::generic::FMod; int min2 = -(FPBits::MAX_BIASED_EXPONENT + FPBits::SIG_LEN) / 2; int max2 = 3 + FPBits::MAX_BIASED_EXPONENT / 2; for (T by : TEST_BASES) { for (int iy = min2; iy < max2; iy++) { T y = by * LIBC_NAMESPACE::fputil::ldexp(2.0, iy); FPBits y_bits(y); if (y_bits.is_zero() || !y_bits.is_finite()) continue; for (T bx : TEST_BASES) { for (int ix = min2; ix < max2; ix++) { T x = bx * LIBC_NAMESPACE::fputil::ldexp(2.0, ix); if (!FPBits(x).is_finite()) continue; T result = FMod::eval(x, y); mpfr::BinaryInput input{x, y}; EXPECT_MPFR_MATCH(mpfr::Operation::Fmod, input, result, 0.0); } } } } } }; using LlvmLibcFModFloatTest = LlvmLibcFModTest; TEST_F(LlvmLibcFModFloatTest, ExtensiveTest) { testExtensive(); } using LlvmLibcFModFloatInvTest = LlvmLibcFModTest; TEST_F(LlvmLibcFModFloatInvTest, ExtensiveTest) { testExtensive(); } using LlvmLibcFModDoubleTest = LlvmLibcFModTest; TEST_F(LlvmLibcFModDoubleTest, ExtensiveTest) { testExtensive(); } using LlvmLibcFModDoubleInvTest = LlvmLibcFModTest; TEST_F(LlvmLibcFModDoubleInvTest, ExtensiveTest) { testExtensive(); }