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