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>::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 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 = neg_zero; 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 *>(&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 expectedBits = MAX_SUBNORMAL - 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)) + MIN_NORMAL; 88 expected = *reinterpret_cast<T *>(&expectedBits); 89 ASSERT_FP_EQ(result, expected); 90 91 result = func(x, 0); 92 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + MAX_SUBNORMAL - 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 *>(&MIN_SUBNORMAL); 98 result = func(x, 1); 99 expectedBits = MIN_SUBNORMAL + 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)) + MIN_SUBNORMAL + 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 *>(&MIN_NORMAL); 113 result = func(x, 0); 114 expectedBits = MAX_SUBNORMAL; 115 expected = *reinterpret_cast<T *>(&expectedBits); 116 ASSERT_FP_EQ(result, expected); 117 118 result = func(x, inf); 119 expectedBits = MIN_NORMAL + 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)) + MAX_SUBNORMAL; 126 expected = *reinterpret_cast<T *>(&expectedBits); 127 ASSERT_FP_EQ(result, expected); 128 129 result = func(x, -inf); 130 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + MIN_NORMAL + 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 *>(&MAX_NORMAL); 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 = MAX_NORMAL; 146 expected = *reinterpret_cast<T *>(&expectedBits); 147 ASSERT_FP_EQ(result, expected); 148 ASSERT_FP_EQ(func(x, inf), inf); 149 150 x = neg_inf; 151 result = func(x, 0); 152 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + MAX_NORMAL; 153 expected = *reinterpret_cast<T *>(&expectedBits); 154 ASSERT_FP_EQ(result, expected); 155 ASSERT_FP_EQ(func(x, neg_inf), neg_inf); 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.get_unbiased_exponent(), 163 uint16_t(xBits.get_unbiased_exponent() - 1)); 164 ASSERT_EQ(resultBits.get_mantissa(), 165 (UIntType(1) << MantissaWidth::VALUE) - 1); 166 167 result = func(x, T(33.0)); 168 resultBits = FPBits(result); 169 ASSERT_EQ(resultBits.get_unbiased_exponent(), 170 xBits.get_unbiased_exponent()); 171 ASSERT_EQ(resultBits.get_mantissa(), xBits.get_mantissa() + UIntType(1)); 172 173 x = -x; 174 175 result = func(x, 0); 176 resultBits = FPBits(result); 177 ASSERT_EQ(resultBits.get_unbiased_exponent(), 178 uint16_t(xBits.get_unbiased_exponent() - 1)); 179 ASSERT_EQ(resultBits.get_mantissa(), 180 (UIntType(1) << MantissaWidth::VALUE) - 1); 181 182 result = func(x, T(-33.0)); 183 resultBits = FPBits(result); 184 ASSERT_EQ(resultBits.get_unbiased_exponent(), 185 xBits.get_unbiased_exponent()); 186 ASSERT_EQ(resultBits.get_mantissa(), xBits.get_mantissa() + UIntType(1)); 187 } 188 }; 189 190 #define LIST_NEXTAFTER_TESTS(T, func) \ 191 using LlvmLibcNextAfterTest = NextAfterTestTemplate<T>; \ 192 TEST_F(LlvmLibcNextAfterTest, TestNaN) { testNaN(&func); } \ 193 TEST_F(LlvmLibcNextAfterTest, TestBoundaries) { testBoundaries(&func); } 194 195 #endif // LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H 196