1 //===-- Utility class to test logb[f|l] -------------------------*- 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 9 #include "src/__support/FPUtil/ManipulationFunctions.h" 10 #include "utils/MPFRWrapper/MPFRUtils.h" 11 #include "utils/UnitTest/FPMatcher.h" 12 #include "utils/UnitTest/Test.h" 13 14 #include <math.h> 15 16 namespace mpfr = __llvm_libc::testing::mpfr; 17 18 template <typename T> class LogbTest : public __llvm_libc::testing::Test { 19 20 DECLARE_SPECIAL_CONSTANTS(T) 21 22 static constexpr UIntType HIDDEN_BIT = 23 UIntType(1) << __llvm_libc::fputil::MantissaWidth<T>::VALUE; 24 25 public: 26 typedef T (*LogbFunc)(T); 27 testSpecialNumbers(LogbFunc func)28 void testSpecialNumbers(LogbFunc func) { 29 ASSERT_FP_EQ(aNaN, func(aNaN)); 30 ASSERT_FP_EQ(inf, func(inf)); 31 ASSERT_FP_EQ(inf, func(neg_inf)); 32 ASSERT_FP_EQ(neg_inf, func(0.0)); 33 ASSERT_FP_EQ(neg_inf, func(-0.0)); 34 } 35 testPowersOfTwo(LogbFunc func)36 void testPowersOfTwo(LogbFunc func) { 37 EXPECT_FP_EQ(T(0.0), func(T(1.0))); 38 EXPECT_FP_EQ(T(0.0), func(T(-1.0))); 39 40 EXPECT_FP_EQ(T(1.0), func(T(2.0))); 41 EXPECT_FP_EQ(T(1.0), func(T(-2.0))); 42 43 EXPECT_FP_EQ(T(2.0), func(T(4.0))); 44 EXPECT_FP_EQ(T(2.0), func(T(-4.0))); 45 46 EXPECT_FP_EQ(T(3.0), func(T(8.0))); 47 EXPECT_FP_EQ(T(3.0), func(T(-8.0))); 48 49 EXPECT_FP_EQ(T(4.0), func(T(16.0))); 50 EXPECT_FP_EQ(T(4.0), func(T(-16.0))); 51 52 EXPECT_FP_EQ(T(5.0), func(T(32.0))); 53 EXPECT_FP_EQ(T(5.0), func(T(-32.0))); 54 } 55 testSomeIntegers(LogbFunc func)56 void testSomeIntegers(LogbFunc func) { 57 EXPECT_FP_EQ(T(1.0), func(T(3.0))); 58 EXPECT_FP_EQ(T(1.0), func(T(-3.0))); 59 60 EXPECT_FP_EQ(T(2.0), func(T(7.0))); 61 EXPECT_FP_EQ(T(2.0), func(T(-7.0))); 62 63 EXPECT_FP_EQ(T(3.0), func(T(10.0))); 64 EXPECT_FP_EQ(T(3.0), func(T(-10.0))); 65 66 EXPECT_FP_EQ(T(4.0), func(T(31.0))); 67 EXPECT_FP_EQ(T(4.0), func(T(-31.0))); 68 69 EXPECT_FP_EQ(T(5.0), func(T(55.0))); 70 EXPECT_FP_EQ(T(5.0), func(T(-55.0))); 71 } 72 testRange(LogbFunc func)73 void testRange(LogbFunc func) { 74 using UIntType = typename FPBits::UIntType; 75 constexpr UIntType COUNT = 10000000; 76 constexpr UIntType STEP = UIntType(-1) / COUNT; 77 for (UIntType i = 0, v = 0; i <= COUNT; ++i, v += STEP) { 78 T x = static_cast<T>(FPBits(v)); 79 if (isnan(x) || isinf(x) || x == 0.0l) 80 continue; 81 82 int exponent; 83 __llvm_libc::fputil::frexp(x, exponent); 84 ASSERT_FP_EQ(T(exponent), func(x) + T(1.0)); 85 } 86 } 87 }; 88 89 #define LIST_LOGB_TESTS(T, func) \ 90 using LlvmLibcLogbTest = LogbTest<T>; \ 91 TEST_F(LlvmLibcLogbTest, SpecialNumbers) { testSpecialNumbers(&func); } \ 92 TEST_F(LlvmLibcLogbTest, PowersOfTwo) { testPowersOfTwo(&func); } \ 93 TEST_F(LlvmLibcLogbTest, SomeIntegers) { testSomeIntegers(&func); } \ 94 TEST_F(LlvmLibcLogbTest, InRange) { testRange(&func); } 95