xref: /aosp_15_r20/external/llvm-libc/test/src/math/smoke/FrexpTest.h (revision 71db0c75aadcf003ffe3238005f61d7618a3fead)
1 //===-- Utility class to test frexp[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 "test/UnitTest/FEnvSafeTest.h"
10 #include "test/UnitTest/FPMatcher.h"
11 #include "test/UnitTest/Test.h"
12 
13 template <typename T>
14 class FrexpTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {
15 
16   DECLARE_SPECIAL_CONSTANTS(T)
17 
18 public:
19   typedef T (*FrexpFunc)(T, int *);
20 
testSpecialNumbers(FrexpFunc func)21   void testSpecialNumbers(FrexpFunc func) {
22     int exponent;
23     EXPECT_FP_EQ_ALL_ROUNDING(aNaN, func(aNaN, &exponent));
24 #ifdef LIBC_FREXP_INF_NAN_EXPONENT
25     EXPECT_EQ(LIBC_FREXP_INF_NAN_EXPONENT, exponent);
26 #endif // LIBC_FREXP_INF_NAN_EXPONENT
27 
28     EXPECT_FP_EQ_ALL_ROUNDING(inf, func(inf, &exponent));
29 #ifdef LIBC_FREXP_INF_NAN_EXPONENT
30     EXPECT_EQ(LIBC_FREXP_INF_NAN_EXPONENT, exponent);
31 #endif // LIBC_FREXP_INF_NAN_EXPONENT
32 
33     EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, func(neg_inf, &exponent));
34 #ifdef LIBC_FREXP_INF_NAN_EXPONENT
35     EXPECT_EQ(LIBC_FREXP_INF_NAN_EXPONENT, exponent);
36 #endif // LIBC_FREXP_INF_NAN_EXPONENT
37 
38     EXPECT_FP_EQ_ALL_ROUNDING(zero, func(zero, &exponent));
39     EXPECT_EQ(exponent, 0);
40 
41     EXPECT_FP_EQ_ALL_ROUNDING(-zero, func(-zero, &exponent));
42     EXPECT_EQ(exponent, 0);
43   }
44 
testPowersOfTwo(FrexpFunc func)45   void testPowersOfTwo(FrexpFunc func) {
46     int exponent;
47 
48     EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(1.0), &exponent));
49     EXPECT_EQ(exponent, 1);
50     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-1.0), &exponent));
51     EXPECT_EQ(exponent, 1);
52 
53     EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(2.0), &exponent));
54     EXPECT_EQ(exponent, 2);
55     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-2.0), &exponent));
56     EXPECT_EQ(exponent, 2);
57 
58     EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(4.0), &exponent));
59     EXPECT_EQ(exponent, 3);
60     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-4.0), &exponent));
61     EXPECT_EQ(exponent, 3);
62 
63     EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(8.0), &exponent));
64     EXPECT_EQ(exponent, 4);
65     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-8.0), &exponent));
66     EXPECT_EQ(exponent, 4);
67 
68     EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(16.0), &exponent));
69     EXPECT_EQ(exponent, 5);
70     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-16.0), &exponent));
71     EXPECT_EQ(exponent, 5);
72 
73     EXPECT_FP_EQ_ALL_ROUNDING(T(0.5), func(T(32.0), &exponent));
74     EXPECT_EQ(exponent, 6);
75     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.5), func(T(-32.0), &exponent));
76     EXPECT_EQ(exponent, 6);
77   }
78 
testSomeIntegers(FrexpFunc func)79   void testSomeIntegers(FrexpFunc func) {
80     int exponent;
81 
82     EXPECT_FP_EQ_ALL_ROUNDING(T(0.75), func(T(24.0), &exponent));
83     EXPECT_EQ(exponent, 5);
84     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.75), func(T(-24.0), &exponent));
85     EXPECT_EQ(exponent, 5);
86 
87     EXPECT_FP_EQ_ALL_ROUNDING(T(0.625), func(T(40.0), &exponent));
88     EXPECT_EQ(exponent, 6);
89     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.625), func(T(-40.0), &exponent));
90     EXPECT_EQ(exponent, 6);
91 
92     EXPECT_FP_EQ_ALL_ROUNDING(T(0.78125), func(T(800.0), &exponent));
93     EXPECT_EQ(exponent, 10);
94     EXPECT_FP_EQ_ALL_ROUNDING(T(-0.78125), func(T(-800.0), &exponent));
95     EXPECT_EQ(exponent, 10);
96   }
97 };
98 
99 #define LIST_FREXP_TESTS(T, func)                                              \
100   using LlvmLibcFrexpTest = FrexpTest<T>;                                      \
101   TEST_F(LlvmLibcFrexpTest, SpecialNumbers) { testSpecialNumbers(&func); }     \
102   TEST_F(LlvmLibcFrexpTest, PowersOfTwo) { testPowersOfTwo(&func); }           \
103   TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); }         \
104   static_assert(true, "Require semicolon.")
105