1*71db0c75SAndroid Build Coastguard Worker //===-- Utility class to test floor[f|l] ------------------------*- C++ -*-===// 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 "src/__support/FPUtil/BasicOperations.h" 10*71db0c75SAndroid Build Coastguard Worker #include "src/__support/FPUtil/NearestIntegerOperations.h" 11*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/FEnvSafeTest.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 #include "hdr/math_macros.h" 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 template <typename T> 21*71db0c75SAndroid Build Coastguard Worker class ModfTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { 22*71db0c75SAndroid Build Coastguard Worker 23*71db0c75SAndroid Build Coastguard Worker DECLARE_SPECIAL_CONSTANTS(T) 24*71db0c75SAndroid Build Coastguard Worker 25*71db0c75SAndroid Build Coastguard Worker public: 26*71db0c75SAndroid Build Coastguard Worker typedef T (*ModfFunc)(T, T *); 27*71db0c75SAndroid Build Coastguard Worker testSpecialNumbers(ModfFunc func)28*71db0c75SAndroid Build Coastguard Worker void testSpecialNumbers(ModfFunc func) { 29*71db0c75SAndroid Build Coastguard Worker T integral; 30*71db0c75SAndroid Build Coastguard Worker 31*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(zero, func(zero, &integral)); 32*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(integral, zero); 33*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(neg_zero, func(neg_zero, &integral)); 34*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(integral, neg_zero); 35*71db0c75SAndroid Build Coastguard Worker 36*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(zero, func(inf, &integral)); 37*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(inf, integral); 38*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(neg_zero, func(neg_inf, &integral)); 39*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(neg_inf, integral); 40*71db0c75SAndroid Build Coastguard Worker 41*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(aNaN, func(aNaN, &integral)); 42*71db0c75SAndroid Build Coastguard Worker } 43*71db0c75SAndroid Build Coastguard Worker testIntegers(ModfFunc func)44*71db0c75SAndroid Build Coastguard Worker void testIntegers(ModfFunc func) { 45*71db0c75SAndroid Build Coastguard Worker T integral; 46*71db0c75SAndroid Build Coastguard Worker 47*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(0.0), func(T(1.0), &integral)); 48*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(1.0), integral); 49*71db0c75SAndroid Build Coastguard Worker 50*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-0.0), func(T(-1.0), &integral)); 51*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-1.0), integral); 52*71db0c75SAndroid Build Coastguard Worker 53*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(0.0), func(T(10.0), &integral)); 54*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(10.0), integral); 55*71db0c75SAndroid Build Coastguard Worker 56*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-0.0), func(T(-10.0), &integral)); 57*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-10.0), integral); 58*71db0c75SAndroid Build Coastguard Worker 59*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(0.0), func(T(12345.0), &integral)); 60*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(12345.0), integral); 61*71db0c75SAndroid Build Coastguard Worker 62*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-0.0), func(T(-12345.0), &integral)); 63*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-12345.0), integral); 64*71db0c75SAndroid Build Coastguard Worker } 65*71db0c75SAndroid Build Coastguard Worker testFractions(ModfFunc func)66*71db0c75SAndroid Build Coastguard Worker void testFractions(ModfFunc func) { 67*71db0c75SAndroid Build Coastguard Worker T integral; 68*71db0c75SAndroid Build Coastguard Worker 69*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(0.5), func(T(1.5), &integral)); 70*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(integral, T(1.0)); 71*71db0c75SAndroid Build Coastguard Worker 72*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-0.5), func(T(-1.5), &integral)); 73*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(integral, T(-1.0)); 74*71db0c75SAndroid Build Coastguard Worker 75*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(0.75), func(T(10.75), &integral)); 76*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(integral, T(10.0)); 77*71db0c75SAndroid Build Coastguard Worker 78*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-0.75), func(T(-10.75), &integral)); 79*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(integral, T(-10.0)); 80*71db0c75SAndroid Build Coastguard Worker 81*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(0.125), func(T(100.125), &integral)); 82*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(integral, T(100.0)); 83*71db0c75SAndroid Build Coastguard Worker 84*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(T(-0.125), func(T(-100.125), &integral)); 85*71db0c75SAndroid Build Coastguard Worker EXPECT_FP_EQ(integral, T(-100.0)); 86*71db0c75SAndroid Build Coastguard Worker } 87*71db0c75SAndroid Build Coastguard Worker testRange(ModfFunc func)88*71db0c75SAndroid Build Coastguard Worker void testRange(ModfFunc func) { 89*71db0c75SAndroid Build Coastguard Worker constexpr StorageType COUNT = 100'000; 90*71db0c75SAndroid Build Coastguard Worker constexpr StorageType STEP = STORAGE_MAX / COUNT; 91*71db0c75SAndroid Build Coastguard Worker for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { 92*71db0c75SAndroid Build Coastguard Worker T x = FPBits(v).get_val(); 93*71db0c75SAndroid Build Coastguard Worker if (FPBits(v).is_nan() || FPBits(v).is_inf() || x == T(0.0)) 94*71db0c75SAndroid Build Coastguard Worker continue; 95*71db0c75SAndroid Build Coastguard Worker 96*71db0c75SAndroid Build Coastguard Worker T integral; 97*71db0c75SAndroid Build Coastguard Worker T frac = func(x, &integral); 98*71db0c75SAndroid Build Coastguard Worker ASSERT_TRUE(LIBC_NAMESPACE::fputil::abs(frac) < 1.0l); 99*71db0c75SAndroid Build Coastguard Worker ASSERT_TRUE(LIBC_NAMESPACE::fputil::trunc(x) == integral); 100*71db0c75SAndroid Build Coastguard Worker ASSERT_TRUE(integral + frac == x); 101*71db0c75SAndroid Build Coastguard Worker } 102*71db0c75SAndroid Build Coastguard Worker } 103*71db0c75SAndroid Build Coastguard Worker }; 104*71db0c75SAndroid Build Coastguard Worker 105*71db0c75SAndroid Build Coastguard Worker #define LIST_MODF_TESTS(T, func) \ 106*71db0c75SAndroid Build Coastguard Worker using LlvmLibcModfTest = ModfTest<T>; \ 107*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibcModfTest, SpecialNumbers) { testSpecialNumbers(&func); } \ 108*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibcModfTest, RoundedNubmers) { testIntegers(&func); } \ 109*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibcModfTest, Fractions) { testFractions(&func); } \ 110*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibcModfTest, Range) { testRange(&func); } 111