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 "hdr/math_macros.h" 13 #include "src/__support/CPP/bit.h" 14 #include "src/__support/CPP/type_traits.h" 15 #include "src/__support/FPUtil/BasicOperations.h" 16 #include "src/__support/FPUtil/FPBits.h" 17 #include "test/UnitTest/FEnvSafeTest.h" 18 #include "test/UnitTest/FPMatcher.h" 19 #include "test/UnitTest/Test.h" 20 21 using LIBC_NAMESPACE::Sign; 22 23 template <typename T> 24 class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::FEnvSafeTest { 25 using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; 26 using StorageType = typename FPBits::StorageType; 27 28 const T inf = FPBits::inf(Sign::POS).get_val(); 29 const T neg_inf = FPBits::inf(Sign::NEG).get_val(); 30 const T zero = FPBits::zero(Sign::POS).get_val(); 31 const T neg_zero = FPBits::zero(Sign::NEG).get_val(); 32 const T nan = FPBits::quiet_nan().get_val(); 33 34 const StorageType min_subnormal = FPBits::min_subnormal().uintval(); 35 const StorageType max_subnormal = FPBits::max_subnormal().uintval(); 36 const StorageType min_normal = FPBits::min_normal().uintval(); 37 const StorageType max_normal = FPBits::max_normal().uintval(); 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 StorageType expected_bits = 1; 55 T expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 56 ASSERT_FP_EQ(result, expected); 57 58 result = func(x, T(-1)); 59 expected_bits = FPBits::SIGN_MASK + 1; 60 expected = LIBC_NAMESPACE::cpp::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 = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 67 ASSERT_FP_EQ(result, expected); 68 69 result = func(x, -1); 70 expected_bits = FPBits::SIGN_MASK + 1; 71 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 72 ASSERT_FP_EQ(result, expected); 73 74 // 'from' is max subnormal value. 75 x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_subnormal); 76 result = func(x, 1); 77 expected = LIBC_NAMESPACE::cpp::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 = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 83 ASSERT_FP_EQ(result, expected); 84 85 x = -x; 86 87 result = func(x, -1); 88 expected_bits = FPBits::SIGN_MASK + min_normal; 89 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 90 ASSERT_FP_EQ(result, expected); 91 92 result = func(x, 0); 93 expected_bits = FPBits::SIGN_MASK + max_subnormal - 1; 94 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 95 ASSERT_FP_EQ(result, expected); 96 97 // 'from' is min subnormal value. 98 x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_subnormal); 99 result = func(x, 1); 100 expected_bits = min_subnormal + 1; 101 expected = LIBC_NAMESPACE::cpp::bit_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 = FPBits::SIGN_MASK + min_subnormal + 1; 108 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 109 ASSERT_FP_EQ(result, expected); 110 ASSERT_FP_EQ(func(x, 0), T(-0.0)); 111 112 // 'from' is min normal. 113 x = LIBC_NAMESPACE::cpp::bit_cast<T>(min_normal); 114 result = func(x, 0); 115 expected_bits = max_subnormal; 116 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 117 ASSERT_FP_EQ(result, expected); 118 119 result = func(x, inf); 120 expected_bits = min_normal + 1; 121 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 122 ASSERT_FP_EQ(result, expected); 123 124 x = -x; 125 result = func(x, 0); 126 expected_bits = FPBits::SIGN_MASK + max_subnormal; 127 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 128 ASSERT_FP_EQ(result, expected); 129 130 result = func(x, -inf); 131 expected_bits = FPBits::SIGN_MASK + min_normal + 1; 132 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 133 ASSERT_FP_EQ(result, expected); 134 135 // 'from' is max normal and 'to' is infinity. 136 x = LIBC_NAMESPACE::cpp::bit_cast<T>(max_normal); 137 result = func(x, inf); 138 ASSERT_FP_EQ(result, inf); 139 140 result = func(-x, -inf); 141 ASSERT_FP_EQ(result, -inf); 142 143 // 'from' is infinity. 144 x = inf; 145 result = func(x, 0); 146 expected_bits = max_normal; 147 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 148 ASSERT_FP_EQ(result, expected); 149 ASSERT_FP_EQ(func(x, inf), inf); 150 151 x = neg_inf; 152 result = func(x, 0); 153 expected_bits = FPBits::SIGN_MASK + max_normal; 154 expected = LIBC_NAMESPACE::cpp::bit_cast<T>(expected_bits); 155 ASSERT_FP_EQ(result, expected); 156 ASSERT_FP_EQ(func(x, neg_inf), neg_inf); 157 158 // 'from' is a power of 2. 159 x = T(32.0); 160 result = func(x, 0); 161 FPBits x_bits = FPBits(x); 162 FPBits result_bits = FPBits(result); 163 ASSERT_EQ(result_bits.get_biased_exponent(), 164 uint16_t(x_bits.get_biased_exponent() - 1)); 165 ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK); 166 167 result = func(x, T(33.0)); 168 result_bits = FPBits(result); 169 ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent()); 170 ASSERT_EQ(result_bits.get_mantissa(), 171 x_bits.get_mantissa() + StorageType(1)); 172 173 x = -x; 174 175 result = func(x, 0); 176 result_bits = FPBits(result); 177 ASSERT_EQ(result_bits.get_biased_exponent(), 178 uint16_t(x_bits.get_biased_exponent() - 1)); 179 ASSERT_EQ(result_bits.get_mantissa(), FPBits::FRACTION_MASK); 180 181 result = func(x, T(-33.0)); 182 result_bits = FPBits(result); 183 ASSERT_EQ(result_bits.get_biased_exponent(), x_bits.get_biased_exponent()); 184 ASSERT_EQ(result_bits.get_mantissa(), 185 x_bits.get_mantissa() + StorageType(1)); 186 } 187 }; 188 189 #define LIST_NEXTAFTER_TESTS(T, func) \ 190 using LlvmLibcNextAfterTest = NextAfterTestTemplate<T>; \ 191 TEST_F(LlvmLibcNextAfterTest, TestNaN) { testNaN(&func); } \ 192 TEST_F(LlvmLibcNextAfterTest, TestBoundaries) { testBoundaries(&func); } 193 194 #endif // LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H 195