1 //===-- Utility class to test different flavors of nextafter ----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
10 #define LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H
12 #include "src/__support/CPP/bit.h"
13 #include "src/__support/CPP/type_traits.h"
14 #include "src/__support/FPUtil/BasicOperations.h"
15 #include "src/__support/FPUtil/FPBits.h"
16 #include "test/UnitTest/FPMatcher.h"
17 #include "test/UnitTest/Test.h"
21 class NextAfterTestTemplate
: public LIBC_NAMESPACE::testing::Test
{
22 using FPBits
= LIBC_NAMESPACE::fputil::FPBits
<T
>;
23 using MantissaWidth
= LIBC_NAMESPACE::fputil::MantissaWidth
<T
>;
24 using UIntType
= typename
FPBits::UIntType
;
26 static constexpr int BIT_WIDTH_OF_TYPE
=
27 LIBC_NAMESPACE::fputil::FloatProperties
<T
>::BIT_WIDTH
;
29 const T zero
= T(FPBits::zero());
30 const T neg_zero
= T(FPBits::neg_zero());
31 const T inf
= T(FPBits::inf());
32 const T neg_inf
= T(FPBits::neg_inf());
33 const T nan
= T(FPBits::build_quiet_nan(1));
34 const UIntType min_subnormal
= FPBits::MIN_SUBNORMAL
;
35 const UIntType max_subnormal
= FPBits::MAX_SUBNORMAL
;
36 const UIntType min_normal
= FPBits::MIN_NORMAL
;
37 const UIntType max_normal
= FPBits::MAX_NORMAL
;
40 typedef T (*NextAfterFunc
)(T
, T
);
42 void testNaN(NextAfterFunc func
) {
43 ASSERT_FP_EQ(func(nan
, 0), nan
);
44 ASSERT_FP_EQ(func(0, nan
), nan
);
47 void testBoundaries(NextAfterFunc func
) {
48 ASSERT_FP_EQ(func(zero
, neg_zero
), neg_zero
);
49 ASSERT_FP_EQ(func(neg_zero
, zero
), zero
);
51 // 'from' is zero|neg_zero.
53 T result
= func(x
, T(1));
54 UIntType expected_bits
= 1;
55 T expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
56 ASSERT_FP_EQ(result
, expected
);
58 result
= func(x
, T(-1));
59 expected_bits
= (UIntType(1) << (BIT_WIDTH_OF_TYPE
- 1)) + 1;
60 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
61 ASSERT_FP_EQ(result
, expected
);
66 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
67 ASSERT_FP_EQ(result
, expected
);
70 expected_bits
= (UIntType(1) << (BIT_WIDTH_OF_TYPE
- 1)) + 1;
71 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
72 ASSERT_FP_EQ(result
, expected
);
74 // 'from' is max subnormal value.
75 x
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(max_subnormal
);
77 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(min_normal
);
78 ASSERT_FP_EQ(result
, expected
);
81 expected_bits
= max_subnormal
- 1;
82 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
83 ASSERT_FP_EQ(result
, expected
);
88 expected_bits
= (UIntType(1) << (BIT_WIDTH_OF_TYPE
- 1)) + min_normal
;
89 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
90 ASSERT_FP_EQ(result
, expected
);
94 (UIntType(1) << (BIT_WIDTH_OF_TYPE
- 1)) + max_subnormal
- 1;
95 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
96 ASSERT_FP_EQ(result
, expected
);
98 // 'from' is min subnormal value.
99 x
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(min_subnormal
);
101 expected_bits
= min_subnormal
+ 1;
102 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
103 ASSERT_FP_EQ(result
, expected
);
104 ASSERT_FP_EQ(func(x
, 0), 0);
107 result
= func(x
, -1);
109 (UIntType(1) << (BIT_WIDTH_OF_TYPE
- 1)) + min_subnormal
+ 1;
110 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
111 ASSERT_FP_EQ(result
, expected
);
112 ASSERT_FP_EQ(func(x
, 0), T(-0.0));
114 // 'from' is min normal.
115 x
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(min_normal
);
117 expected_bits
= max_subnormal
;
118 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
119 ASSERT_FP_EQ(result
, expected
);
121 result
= func(x
, inf
);
122 expected_bits
= min_normal
+ 1;
123 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
124 ASSERT_FP_EQ(result
, expected
);
128 expected_bits
= (UIntType(1) << (BIT_WIDTH_OF_TYPE
- 1)) + max_subnormal
;
129 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
130 ASSERT_FP_EQ(result
, expected
);
132 result
= func(x
, -inf
);
133 expected_bits
= (UIntType(1) << (BIT_WIDTH_OF_TYPE
- 1)) + min_normal
+ 1;
134 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
135 ASSERT_FP_EQ(result
, expected
);
137 // 'from' is max normal and 'to' is infinity.
138 x
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(max_normal
);
139 result
= func(x
, inf
);
140 ASSERT_FP_EQ(result
, inf
);
142 result
= func(-x
, -inf
);
143 ASSERT_FP_EQ(result
, -inf
);
145 // 'from' is infinity.
148 expected_bits
= max_normal
;
149 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
150 ASSERT_FP_EQ(result
, expected
);
151 ASSERT_FP_EQ(func(x
, inf
), inf
);
155 expected_bits
= (UIntType(1) << (BIT_WIDTH_OF_TYPE
- 1)) + max_normal
;
156 expected
= LIBC_NAMESPACE::cpp::bit_cast
<T
>(expected_bits
);
157 ASSERT_FP_EQ(result
, expected
);
158 ASSERT_FP_EQ(func(x
, neg_inf
), neg_inf
);
160 // 'from' is a power of 2.
163 FPBits x_bits
= FPBits(x
);
164 FPBits result_bits
= FPBits(result
);
165 ASSERT_EQ(result_bits
.get_unbiased_exponent(),
166 uint16_t(x_bits
.get_unbiased_exponent() - 1));
167 ASSERT_EQ(result_bits
.get_mantissa(),
168 (UIntType(1) << MantissaWidth::VALUE
) - 1);
170 result
= func(x
, T(33.0));
171 result_bits
= FPBits(result
);
172 ASSERT_EQ(result_bits
.get_unbiased_exponent(),
173 x_bits
.get_unbiased_exponent());
174 ASSERT_EQ(result_bits
.get_mantissa(), x_bits
.get_mantissa() + UIntType(1));
179 result_bits
= FPBits(result
);
180 ASSERT_EQ(result_bits
.get_unbiased_exponent(),
181 uint16_t(x_bits
.get_unbiased_exponent() - 1));
182 ASSERT_EQ(result_bits
.get_mantissa(),
183 (UIntType(1) << MantissaWidth::VALUE
) - 1);
185 result
= func(x
, T(-33.0));
186 result_bits
= FPBits(result
);
187 ASSERT_EQ(result_bits
.get_unbiased_exponent(),
188 x_bits
.get_unbiased_exponent());
189 ASSERT_EQ(result_bits
.get_mantissa(), x_bits
.get_mantissa() + UIntType(1));
193 #define LIST_NEXTAFTER_TESTS(T, func) \
194 using LlvmLibcNextAfterTest = NextAfterTestTemplate<T>; \
195 TEST_F(LlvmLibcNextAfterTest, TestNaN) { testNaN(&func); } \
196 TEST_F(LlvmLibcNextAfterTest, TestBoundaries) { testBoundaries(&func); }
198 #endif // LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H