1 //===-- Utility class to test different flavors of nextafter ----*- 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 #ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
10 #define LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
11 
12 #include "src/__support/CPP/TypeTraits.h"
13 #include "src/__support/FPUtil/BasicOperations.h"
14 #include "src/__support/FPUtil/FPBits.h"
15 #include "utils/UnitTest/FPMatcher.h"
16 #include "utils/UnitTest/Test.h"
17 #include <math.h>
18 
19 template <typename T>
20 class NextAfterTestTemplate : public __llvm_libc::testing::Test {
21   using FPBits = __llvm_libc::fputil::FPBits<T>;
22   using MantissaWidth = __llvm_libc::fputil::MantissaWidth<T>;
23   using UIntType = typename FPBits::UIntType;
24 
25   static constexpr int BIT_WIDTH_OF_TYPE =
26       __llvm_libc::fputil::FloatProperties<T>::BIT_WIDTH;
27 
28   const T zero = T(FPBits::zero());
29   const T neg_zero = T(FPBits::neg_zero());
30   const T inf = T(FPBits::inf());
31   const T neg_inf = T(FPBits::neg_inf());
32   const T nan = T(FPBits::build_nan(1));
33   const UIntType min_subnormal = FPBits::MIN_SUBNORMAL;
34   const UIntType max_subnormal = FPBits::MAX_SUBNORMAL;
35   const UIntType min_normal = FPBits::MIN_NORMAL;
36   const UIntType max_normal = FPBits::MAX_NORMAL;
37 
38 public:
39   typedef T (*NextAfterFunc)(T, T);
40 
41   void testNaN(NextAfterFunc func) {
42     ASSERT_FP_EQ(func(nan, 0), nan);
43     ASSERT_FP_EQ(func(0, nan), nan);
44   }
45 
46   void testBoundaries(NextAfterFunc func) {
47     ASSERT_FP_EQ(func(zero, neg_zero), neg_zero);
48     ASSERT_FP_EQ(func(neg_zero, zero), zero);
49 
50     // 'from' is zero|neg_zero.
51     T x = zero;
52     T result = func(x, T(1));
53     UIntType expected_bits = 1;
54     T expected = *reinterpret_cast<T *>(&expected_bits);
55     ASSERT_FP_EQ(result, expected);
56 
57     result = func(x, T(-1));
58     expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1;
59     expected = *reinterpret_cast<T *>(&expected_bits);
60     ASSERT_FP_EQ(result, expected);
61 
62     x = neg_zero;
63     result = func(x, 1);
64     expected_bits = 1;
65     expected = *reinterpret_cast<T *>(&expected_bits);
66     ASSERT_FP_EQ(result, expected);
67 
68     result = func(x, -1);
69     expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1;
70     expected = *reinterpret_cast<T *>(&expected_bits);
71     ASSERT_FP_EQ(result, expected);
72 
73     // 'from' is max subnormal value.
74     x = *reinterpret_cast<const T *>(&max_subnormal);
75     result = func(x, 1);
76     expected = *reinterpret_cast<const T *>(&min_normal);
77     ASSERT_FP_EQ(result, expected);
78 
79     result = func(x, 0);
80     expected_bits = max_subnormal - 1;
81     expected = *reinterpret_cast<T *>(&expected_bits);
82     ASSERT_FP_EQ(result, expected);
83 
84     x = -x;
85 
86     result = func(x, -1);
87     expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal;
88     expected = *reinterpret_cast<T *>(&expected_bits);
89     ASSERT_FP_EQ(result, expected);
90 
91     result = func(x, 0);
92     expected_bits =
93         (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal - 1;
94     expected = *reinterpret_cast<T *>(&expected_bits);
95     ASSERT_FP_EQ(result, expected);
96 
97     // 'from' is min subnormal value.
98     x = *reinterpret_cast<const T *>(&min_subnormal);
99     result = func(x, 1);
100     expected_bits = min_subnormal + 1;
101     expected = *reinterpret_cast<T *>(&expected_bits);
102     ASSERT_FP_EQ(result, expected);
103     ASSERT_FP_EQ(func(x, 0), 0);
104 
105     x = -x;
106     result = func(x, -1);
107     expected_bits =
108         (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_subnormal + 1;
109     expected = *reinterpret_cast<T *>(&expected_bits);
110     ASSERT_FP_EQ(result, expected);
111     ASSERT_FP_EQ(func(x, 0), T(-0.0));
112 
113     // 'from' is min normal.
114     x = *reinterpret_cast<const T *>(&min_normal);
115     result = func(x, 0);
116     expected_bits = max_subnormal;
117     expected = *reinterpret_cast<T *>(&expected_bits);
118     ASSERT_FP_EQ(result, expected);
119 
120     result = func(x, inf);
121     expected_bits = min_normal + 1;
122     expected = *reinterpret_cast<T *>(&expected_bits);
123     ASSERT_FP_EQ(result, expected);
124 
125     x = -x;
126     result = func(x, 0);
127     expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal;
128     expected = *reinterpret_cast<T *>(&expected_bits);
129     ASSERT_FP_EQ(result, expected);
130 
131     result = func(x, -inf);
132     expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal + 1;
133     expected = *reinterpret_cast<T *>(&expected_bits);
134     ASSERT_FP_EQ(result, expected);
135 
136     // 'from' is max normal and 'to' is infinity.
137     x = *reinterpret_cast<const T *>(&max_normal);
138     result = func(x, inf);
139     ASSERT_FP_EQ(result, inf);
140 
141     result = func(-x, -inf);
142     ASSERT_FP_EQ(result, -inf);
143 
144     // 'from' is infinity.
145     x = inf;
146     result = func(x, 0);
147     expected_bits = max_normal;
148     expected = *reinterpret_cast<T *>(&expected_bits);
149     ASSERT_FP_EQ(result, expected);
150     ASSERT_FP_EQ(func(x, inf), inf);
151 
152     x = neg_inf;
153     result = func(x, 0);
154     expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_normal;
155     expected = *reinterpret_cast<T *>(&expected_bits);
156     ASSERT_FP_EQ(result, expected);
157     ASSERT_FP_EQ(func(x, neg_inf), neg_inf);
158 
159     // 'from' is a power of 2.
160     x = T(32.0);
161     result = func(x, 0);
162     FPBits x_bits = FPBits(x);
163     FPBits result_bits = FPBits(result);
164     ASSERT_EQ(result_bits.get_unbiased_exponent(),
165               uint16_t(x_bits.get_unbiased_exponent() - 1));
166     ASSERT_EQ(result_bits.get_mantissa(),
167               (UIntType(1) << MantissaWidth::VALUE) - 1);
168 
169     result = func(x, T(33.0));
170     result_bits = FPBits(result);
171     ASSERT_EQ(result_bits.get_unbiased_exponent(),
172               x_bits.get_unbiased_exponent());
173     ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1));
174 
175     x = -x;
176 
177     result = func(x, 0);
178     result_bits = FPBits(result);
179     ASSERT_EQ(result_bits.get_unbiased_exponent(),
180               uint16_t(x_bits.get_unbiased_exponent() - 1));
181     ASSERT_EQ(result_bits.get_mantissa(),
182               (UIntType(1) << MantissaWidth::VALUE) - 1);
183 
184     result = func(x, T(-33.0));
185     result_bits = FPBits(result);
186     ASSERT_EQ(result_bits.get_unbiased_exponent(),
187               x_bits.get_unbiased_exponent());
188     ASSERT_EQ(result_bits.get_mantissa(), x_bits.get_mantissa() + UIntType(1));
189   }
190 };
191 
192 #define LIST_NEXTAFTER_TESTS(T, func)                                          \
193   using LlvmLibcNextAfterTest = NextAfterTestTemplate<T>;                      \
194   TEST_F(LlvmLibcNextAfterTest, TestNaN) { testNaN(&func); }                   \
195   TEST_F(LlvmLibcNextAfterTest, TestBoundaries) { testBoundaries(&func); }
196 
197 #endif // LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
198