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 bitWidthOfType =
26       __llvm_libc::fputil::FloatProperties<T>::bitWidth;
27 
28   const T zero = T(FPBits::zero());
29   const T negZero = T(FPBits::negZero());
30   const T inf = T(FPBits::inf());
31   const T negInf = T(FPBits::negInf());
32   const T nan = T(FPBits::buildNaN(1));
33   const UIntType minSubnormal = FPBits::minSubnormal;
34   const UIntType maxSubnormal = FPBits::maxSubnormal;
35   const UIntType minNormal = FPBits::minNormal;
36   const UIntType maxNormal = FPBits::maxNormal;
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, negZero), negZero);
48     ASSERT_FP_EQ(func(negZero, zero), zero);
49 
50     // 'from' is zero|negZero.
51     T x = zero;
52     T result = func(x, T(1));
53     UIntType expectedBits = 1;
54     T expected = *reinterpret_cast<T *>(&expectedBits);
55     ASSERT_FP_EQ(result, expected);
56 
57     result = func(x, T(-1));
58     expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + 1;
59     expected = *reinterpret_cast<T *>(&expectedBits);
60     ASSERT_FP_EQ(result, expected);
61 
62     x = negZero;
63     result = func(x, 1);
64     expectedBits = 1;
65     expected = *reinterpret_cast<T *>(&expectedBits);
66     ASSERT_FP_EQ(result, expected);
67 
68     result = func(x, -1);
69     expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + 1;
70     expected = *reinterpret_cast<T *>(&expectedBits);
71     ASSERT_FP_EQ(result, expected);
72 
73     // 'from' is max subnormal value.
74     x = *reinterpret_cast<const T *>(&maxSubnormal);
75     result = func(x, 1);
76     expected = *reinterpret_cast<const T *>(&minNormal);
77     ASSERT_FP_EQ(result, expected);
78 
79     result = func(x, 0);
80     expectedBits = maxSubnormal - 1;
81     expected = *reinterpret_cast<T *>(&expectedBits);
82     ASSERT_FP_EQ(result, expected);
83 
84     x = -x;
85 
86     result = func(x, -1);
87     expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + minNormal;
88     expected = *reinterpret_cast<T *>(&expectedBits);
89     ASSERT_FP_EQ(result, expected);
90 
91     result = func(x, 0);
92     expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + maxSubnormal - 1;
93     expected = *reinterpret_cast<T *>(&expectedBits);
94     ASSERT_FP_EQ(result, expected);
95 
96     // 'from' is min subnormal value.
97     x = *reinterpret_cast<const T *>(&minSubnormal);
98     result = func(x, 1);
99     expectedBits = minSubnormal + 1;
100     expected = *reinterpret_cast<T *>(&expectedBits);
101     ASSERT_FP_EQ(result, expected);
102     ASSERT_FP_EQ(func(x, 0), 0);
103 
104     x = -x;
105     result = func(x, -1);
106     expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + minSubnormal + 1;
107     expected = *reinterpret_cast<T *>(&expectedBits);
108     ASSERT_FP_EQ(result, expected);
109     ASSERT_FP_EQ(func(x, 0), T(-0.0));
110 
111     // 'from' is min normal.
112     x = *reinterpret_cast<const T *>(&minNormal);
113     result = func(x, 0);
114     expectedBits = maxSubnormal;
115     expected = *reinterpret_cast<T *>(&expectedBits);
116     ASSERT_FP_EQ(result, expected);
117 
118     result = func(x, inf);
119     expectedBits = minNormal + 1;
120     expected = *reinterpret_cast<T *>(&expectedBits);
121     ASSERT_FP_EQ(result, expected);
122 
123     x = -x;
124     result = func(x, 0);
125     expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + maxSubnormal;
126     expected = *reinterpret_cast<T *>(&expectedBits);
127     ASSERT_FP_EQ(result, expected);
128 
129     result = func(x, -inf);
130     expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + minNormal + 1;
131     expected = *reinterpret_cast<T *>(&expectedBits);
132     ASSERT_FP_EQ(result, expected);
133 
134     // 'from' is max normal and 'to' is infinity.
135     x = *reinterpret_cast<const T *>(&maxNormal);
136     result = func(x, inf);
137     ASSERT_FP_EQ(result, inf);
138 
139     result = func(-x, -inf);
140     ASSERT_FP_EQ(result, -inf);
141 
142     // 'from' is infinity.
143     x = inf;
144     result = func(x, 0);
145     expectedBits = maxNormal;
146     expected = *reinterpret_cast<T *>(&expectedBits);
147     ASSERT_FP_EQ(result, expected);
148     ASSERT_FP_EQ(func(x, inf), inf);
149 
150     x = negInf;
151     result = func(x, 0);
152     expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + maxNormal;
153     expected = *reinterpret_cast<T *>(&expectedBits);
154     ASSERT_FP_EQ(result, expected);
155     ASSERT_FP_EQ(func(x, negInf), negInf);
156 
157     // 'from' is a power of 2.
158     x = T(32.0);
159     result = func(x, 0);
160     FPBits xBits = FPBits(x);
161     FPBits resultBits = FPBits(result);
162     ASSERT_EQ(resultBits.getUnbiasedExponent(),
163               uint16_t(xBits.getUnbiasedExponent() - 1));
164     ASSERT_EQ(resultBits.getMantissa(),
165               (UIntType(1) << MantissaWidth::value) - 1);
166 
167     result = func(x, T(33.0));
168     resultBits = FPBits(result);
169     ASSERT_EQ(resultBits.getUnbiasedExponent(), xBits.getUnbiasedExponent());
170     ASSERT_EQ(resultBits.getMantissa(), xBits.getMantissa() + UIntType(1));
171 
172     x = -x;
173 
174     result = func(x, 0);
175     resultBits = FPBits(result);
176     ASSERT_EQ(resultBits.getUnbiasedExponent(),
177               uint16_t(xBits.getUnbiasedExponent() - 1));
178     ASSERT_EQ(resultBits.getMantissa(),
179               (UIntType(1) << MantissaWidth::value) - 1);
180 
181     result = func(x, T(-33.0));
182     resultBits = FPBits(result);
183     ASSERT_EQ(resultBits.getUnbiasedExponent(), xBits.getUnbiasedExponent());
184     ASSERT_EQ(resultBits.getMantissa(), xBits.getMantissa() + UIntType(1));
185   }
186 };
187 
188 #define LIST_NEXTAFTER_TESTS(T, func)                                          \
189   using LlvmLibcNextAfterTest = NextAfterTestTemplate<T>;                      \
190   TEST_F(LlvmLibcNextAfterTest, TestNaN) { testNaN(&func); }                   \
191   TEST_F(LlvmLibcNextAfterTest, TestBoundaries) { testBoundaries(&func); }
192 
193 #endif // LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
194