• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "test/UnitTest/FEnvSafeTest.h"
11 #include "test/UnitTest/FPMatcher.h"
12 #include "test/UnitTest/Test.h"
13 
14 template <typename T>
15 class LogbTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
16 
17   DECLARE_SPECIAL_CONSTANTS(T)
18 
19   static constexpr StorageType HIDDEN_BIT =
20       StorageType(1) << LIBC_NAMESPACE::fputil::FPBits<T>::FRACTION_LEN;
21 
22 public:
23   typedef T (*LogbFunc)(T);
24 
testSpecialNumbers(LogbFunc func)25   void testSpecialNumbers(LogbFunc func) {
26     ASSERT_FP_EQ(aNaN, func(aNaN));
27     ASSERT_FP_EQ(inf, func(inf));
28     ASSERT_FP_EQ(inf, func(neg_inf));
29     ASSERT_FP_EQ(neg_inf, func(0.0));
30     ASSERT_FP_EQ(neg_inf, func(-0.0));
31   }
32 
testPowersOfTwo(LogbFunc func)33   void testPowersOfTwo(LogbFunc func) {
34     EXPECT_FP_EQ(T(0.0), func(T(1.0)));
35     EXPECT_FP_EQ(T(0.0), func(T(-1.0)));
36 
37     EXPECT_FP_EQ(T(1.0), func(T(2.0)));
38     EXPECT_FP_EQ(T(1.0), func(T(-2.0)));
39 
40     EXPECT_FP_EQ(T(2.0), func(T(4.0)));
41     EXPECT_FP_EQ(T(2.0), func(T(-4.0)));
42 
43     EXPECT_FP_EQ(T(3.0), func(T(8.0)));
44     EXPECT_FP_EQ(T(3.0), func(T(-8.0)));
45 
46     EXPECT_FP_EQ(T(4.0), func(T(16.0)));
47     EXPECT_FP_EQ(T(4.0), func(T(-16.0)));
48 
49     EXPECT_FP_EQ(T(5.0), func(T(32.0)));
50     EXPECT_FP_EQ(T(5.0), func(T(-32.0)));
51   }
52 
testSomeIntegers(LogbFunc func)53   void testSomeIntegers(LogbFunc func) {
54     EXPECT_FP_EQ(T(1.0), func(T(3.0)));
55     EXPECT_FP_EQ(T(1.0), func(T(-3.0)));
56 
57     EXPECT_FP_EQ(T(2.0), func(T(7.0)));
58     EXPECT_FP_EQ(T(2.0), func(T(-7.0)));
59 
60     EXPECT_FP_EQ(T(3.0), func(T(10.0)));
61     EXPECT_FP_EQ(T(3.0), func(T(-10.0)));
62 
63     EXPECT_FP_EQ(T(4.0), func(T(31.0)));
64     EXPECT_FP_EQ(T(4.0), func(T(-31.0)));
65 
66     EXPECT_FP_EQ(T(5.0), func(T(55.0)));
67     EXPECT_FP_EQ(T(5.0), func(T(-55.0)));
68   }
69 
testRange(LogbFunc func)70   void testRange(LogbFunc func) {
71     using StorageType = typename FPBits::StorageType;
72     constexpr StorageType COUNT = 100'000;
73     constexpr StorageType STEP = STORAGE_MAX / COUNT;
74     for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
75       FPBits x_bits = FPBits(v);
76       if (x_bits.is_zero() || x_bits.is_inf_or_nan())
77         continue;
78 
79       T x = x_bits.get_val();
80 
81       int exponent;
82       LIBC_NAMESPACE::fputil::frexp(x, exponent);
83       ASSERT_FP_EQ(T(exponent), func(x) + T(1.0));
84     }
85   }
86 };
87 
88 #define LIST_LOGB_TESTS(T, func)                                               \
89   using LlvmLibcLogbTest = LogbTest<T>;                                        \
90   TEST_F(LlvmLibcLogbTest, SpecialNumbers) { testSpecialNumbers(&func); }      \
91   TEST_F(LlvmLibcLogbTest, PowersOfTwo) { testPowersOfTwo(&func); }            \
92   TEST_F(LlvmLibcLogbTest, SomeIntegers) { testSomeIntegers(&func); }          \
93   TEST_F(LlvmLibcLogbTest, InRange) { testRange(&func); }
94