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