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/Bit.h" 13 #include "src/__support/CPP/TypeTraits.h" 14 #include "src/__support/FPUtil/BasicOperations.h" 15 #include "src/__support/FPUtil/FPBits.h" 16 #include "utils/UnitTest/FPMatcher.h" 17 #include "utils/UnitTest/Test.h" 18 #include <math.h> 19 20 template <typename T> 21 class NextAfterTestTemplate : public __llvm_libc::testing::Test { 22 using FPBits = __llvm_libc::fputil::FPBits<T>; 23 using MantissaWidth = __llvm_libc::fputil::MantissaWidth<T>; 24 using UIntType = typename FPBits::UIntType; 25 26 static constexpr int BIT_WIDTH_OF_TYPE = 27 __llvm_libc::fputil::FloatProperties<T>::BIT_WIDTH; 28 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_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; 38 39 public: 40 typedef T (*NextAfterFunc)(T, T); 41 testNaN(NextAfterFunc func)42 void testNaN(NextAfterFunc func) { 43 ASSERT_FP_EQ(func(nan, 0), nan); 44 ASSERT_FP_EQ(func(0, nan), nan); 45 } 46 testBoundaries(NextAfterFunc func)47 void testBoundaries(NextAfterFunc func) { 48 ASSERT_FP_EQ(func(zero, neg_zero), neg_zero); 49 ASSERT_FP_EQ(func(neg_zero, zero), zero); 50 51 // 'from' is zero|neg_zero. 52 T x = zero; 53 T result = func(x, T(1)); 54 UIntType expected_bits = 1; 55 T expected = __llvm_libc::bit_cast<T>(expected_bits); 56 ASSERT_FP_EQ(result, expected); 57 58 result = func(x, T(-1)); 59 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1; 60 expected = __llvm_libc::bit_cast<T>(expected_bits); 61 ASSERT_FP_EQ(result, expected); 62 63 x = neg_zero; 64 result = func(x, 1); 65 expected_bits = 1; 66 expected = __llvm_libc::bit_cast<T>(expected_bits); 67 ASSERT_FP_EQ(result, expected); 68 69 result = func(x, -1); 70 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + 1; 71 expected = __llvm_libc::bit_cast<T>(expected_bits); 72 ASSERT_FP_EQ(result, expected); 73 74 // 'from' is max subnormal value. 75 x = __llvm_libc::bit_cast<T>(max_subnormal); 76 result = func(x, 1); 77 expected = __llvm_libc::bit_cast<T>(min_normal); 78 ASSERT_FP_EQ(result, expected); 79 80 result = func(x, 0); 81 expected_bits = max_subnormal - 1; 82 expected = __llvm_libc::bit_cast<T>(expected_bits); 83 ASSERT_FP_EQ(result, expected); 84 85 x = -x; 86 87 result = func(x, -1); 88 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal; 89 expected = __llvm_libc::bit_cast<T>(expected_bits); 90 ASSERT_FP_EQ(result, expected); 91 92 result = func(x, 0); 93 expected_bits = 94 (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal - 1; 95 expected = __llvm_libc::bit_cast<T>(expected_bits); 96 ASSERT_FP_EQ(result, expected); 97 98 // 'from' is min subnormal value. 99 x = __llvm_libc::bit_cast<T>(min_subnormal); 100 result = func(x, 1); 101 expected_bits = min_subnormal + 1; 102 expected = __llvm_libc::bit_cast<T>(expected_bits); 103 ASSERT_FP_EQ(result, expected); 104 ASSERT_FP_EQ(func(x, 0), 0); 105 106 x = -x; 107 result = func(x, -1); 108 expected_bits = 109 (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_subnormal + 1; 110 expected = __llvm_libc::bit_cast<T>(expected_bits); 111 ASSERT_FP_EQ(result, expected); 112 ASSERT_FP_EQ(func(x, 0), T(-0.0)); 113 114 // 'from' is min normal. 115 x = __llvm_libc::bit_cast<T>(min_normal); 116 result = func(x, 0); 117 expected_bits = max_subnormal; 118 expected = __llvm_libc::bit_cast<T>(expected_bits); 119 ASSERT_FP_EQ(result, expected); 120 121 result = func(x, inf); 122 expected_bits = min_normal + 1; 123 expected = __llvm_libc::bit_cast<T>(expected_bits); 124 ASSERT_FP_EQ(result, expected); 125 126 x = -x; 127 result = func(x, 0); 128 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_subnormal; 129 expected = __llvm_libc::bit_cast<T>(expected_bits); 130 ASSERT_FP_EQ(result, expected); 131 132 result = func(x, -inf); 133 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + min_normal + 1; 134 expected = __llvm_libc::bit_cast<T>(expected_bits); 135 ASSERT_FP_EQ(result, expected); 136 137 // 'from' is max normal and 'to' is infinity. 138 x = __llvm_libc::bit_cast<T>(max_normal); 139 result = func(x, inf); 140 ASSERT_FP_EQ(result, inf); 141 142 result = func(-x, -inf); 143 ASSERT_FP_EQ(result, -inf); 144 145 // 'from' is infinity. 146 x = inf; 147 result = func(x, 0); 148 expected_bits = max_normal; 149 expected = __llvm_libc::bit_cast<T>(expected_bits); 150 ASSERT_FP_EQ(result, expected); 151 ASSERT_FP_EQ(func(x, inf), inf); 152 153 x = neg_inf; 154 result = func(x, 0); 155 expected_bits = (UIntType(1) << (BIT_WIDTH_OF_TYPE - 1)) + max_normal; 156 expected = __llvm_libc::bit_cast<T>(expected_bits); 157 ASSERT_FP_EQ(result, expected); 158 ASSERT_FP_EQ(func(x, neg_inf), neg_inf); 159 160 // 'from' is a power of 2. 161 x = T(32.0); 162 result = func(x, 0); 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); 169 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)); 175 176 x = -x; 177 178 result = func(x, 0); 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); 184 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)); 190 } 191 }; 192 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); } 197 198 #endif // LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H 199