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 "utils/CPP/TypeTraits.h" 13 #include "utils/FPUtil/BasicOperations.h" 14 #include "utils/FPUtil/FPBits.h" 15 #include "utils/FPUtil/TestHelpers.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 #if (defined(__x86_64__) || defined(__i386__)) 26 static constexpr int bitWidthOfType = 27 __llvm_libc::cpp::IsSame<T, long double>::Value ? 80 : (sizeof(T) * 8); 28 #else 29 static constexpr int bitWidthOfType = sizeof(T) * 8; 30 #endif 31 32 const T zero = FPBits::zero(); 33 const T negZero = FPBits::negZero(); 34 const T inf = FPBits::inf(); 35 const T negInf = FPBits::negInf(); 36 const T nan = FPBits::buildNaN(1); 37 const UIntType minSubnormal = FPBits::minSubnormal; 38 const UIntType maxSubnormal = FPBits::maxSubnormal; 39 const UIntType minNormal = FPBits::minNormal; 40 const UIntType maxNormal = FPBits::maxNormal; 41 42 public: 43 typedef T (*NextAfterFunc)(T, T); 44 45 void testNaN(NextAfterFunc func) { 46 ASSERT_FP_EQ(func(nan, 0), nan); 47 ASSERT_FP_EQ(func(0, nan), nan); 48 } 49 50 void testBoundaries(NextAfterFunc func) { 51 ASSERT_FP_EQ(func(zero, negZero), negZero); 52 ASSERT_FP_EQ(func(negZero, zero), zero); 53 54 // 'from' is zero|negZero. 55 T x = zero; 56 T result = func(x, T(1)); 57 UIntType expectedBits = 1; 58 T expected = *reinterpret_cast<T *>(&expectedBits); 59 ASSERT_FP_EQ(result, expected); 60 61 result = func(x, T(-1)); 62 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + 1; 63 expected = *reinterpret_cast<T *>(&expectedBits); 64 ASSERT_FP_EQ(result, expected); 65 66 x = negZero; 67 result = func(x, 1); 68 expectedBits = 1; 69 expected = *reinterpret_cast<T *>(&expectedBits); 70 ASSERT_FP_EQ(result, expected); 71 72 result = func(x, -1); 73 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + 1; 74 expected = *reinterpret_cast<T *>(&expectedBits); 75 ASSERT_FP_EQ(result, expected); 76 77 // 'from' is max subnormal value. 78 x = *reinterpret_cast<const T *>(&maxSubnormal); 79 result = func(x, 1); 80 expected = *reinterpret_cast<const T *>(&minNormal); 81 ASSERT_FP_EQ(result, expected); 82 83 result = func(x, 0); 84 expectedBits = maxSubnormal - 1; 85 expected = *reinterpret_cast<T *>(&expectedBits); 86 ASSERT_FP_EQ(result, expected); 87 88 x = -x; 89 90 result = func(x, -1); 91 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + minNormal; 92 expected = *reinterpret_cast<T *>(&expectedBits); 93 ASSERT_FP_EQ(result, expected); 94 95 result = func(x, 0); 96 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + maxSubnormal - 1; 97 expected = *reinterpret_cast<T *>(&expectedBits); 98 ASSERT_FP_EQ(result, expected); 99 100 // 'from' is min subnormal value. 101 x = *reinterpret_cast<const T *>(&minSubnormal); 102 result = func(x, 1); 103 expectedBits = minSubnormal + 1; 104 expected = *reinterpret_cast<T *>(&expectedBits); 105 ASSERT_FP_EQ(result, expected); 106 ASSERT_FP_EQ(func(x, 0), 0); 107 108 x = -x; 109 result = func(x, -1); 110 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + minSubnormal + 1; 111 expected = *reinterpret_cast<T *>(&expectedBits); 112 ASSERT_FP_EQ(result, expected); 113 ASSERT_FP_EQ(func(x, 0), T(-0.0)); 114 115 // 'from' is min normal. 116 x = *reinterpret_cast<const T *>(&minNormal); 117 result = func(x, 0); 118 expectedBits = maxSubnormal; 119 expected = *reinterpret_cast<T *>(&expectedBits); 120 ASSERT_FP_EQ(result, expected); 121 122 result = func(x, inf); 123 expectedBits = minNormal + 1; 124 expected = *reinterpret_cast<T *>(&expectedBits); 125 ASSERT_FP_EQ(result, expected); 126 127 x = -x; 128 result = func(x, 0); 129 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + maxSubnormal; 130 expected = *reinterpret_cast<T *>(&expectedBits); 131 ASSERT_FP_EQ(result, expected); 132 133 result = func(x, -inf); 134 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + minNormal + 1; 135 expected = *reinterpret_cast<T *>(&expectedBits); 136 ASSERT_FP_EQ(result, expected); 137 138 // 'from' is max normal and 'to' is infinity. 139 x = *reinterpret_cast<const T *>(&maxNormal); 140 result = func(x, inf); 141 ASSERT_FP_EQ(result, inf); 142 143 result = func(-x, -inf); 144 ASSERT_FP_EQ(result, -inf); 145 146 // 'from' is infinity. 147 x = inf; 148 result = func(x, 0); 149 expectedBits = maxNormal; 150 expected = *reinterpret_cast<T *>(&expectedBits); 151 ASSERT_FP_EQ(result, expected); 152 ASSERT_FP_EQ(func(x, inf), inf); 153 154 x = negInf; 155 result = func(x, 0); 156 expectedBits = (UIntType(1) << (bitWidthOfType - 1)) + maxNormal; 157 expected = *reinterpret_cast<T *>(&expectedBits); 158 ASSERT_FP_EQ(result, expected); 159 ASSERT_FP_EQ(func(x, negInf), negInf); 160 161 // 'from' is a power of 2. 162 x = T(32.0); 163 result = func(x, 0); 164 FPBits xBits = FPBits(x); 165 FPBits resultBits = FPBits(result); 166 ASSERT_EQ(resultBits.exponent, uint16_t(xBits.exponent - 1)); 167 ASSERT_EQ(resultBits.mantissa, (UIntType(1) << MantissaWidth::value) - 1); 168 169 result = func(x, T(33.0)); 170 resultBits = FPBits(result); 171 ASSERT_EQ(resultBits.exponent, xBits.exponent); 172 ASSERT_EQ(resultBits.mantissa, xBits.mantissa + UIntType(1)); 173 174 x = -x; 175 176 result = func(x, 0); 177 resultBits = FPBits(result); 178 ASSERT_EQ(resultBits.exponent, uint16_t(xBits.exponent - 1)); 179 ASSERT_EQ(resultBits.mantissa, (UIntType(1) << MantissaWidth::value) - 1); 180 181 result = func(x, T(-33.0)); 182 resultBits = FPBits(result); 183 ASSERT_EQ(resultBits.exponent, xBits.exponent); 184 ASSERT_EQ(resultBits.mantissa, xBits.mantissa + 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