195 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H10#define LLVM_LIBC_TEST_SRC_MATH_NEXTAFTERTEST_H11 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 21using LIBC_NAMESPACE::Sign;22 23template <typename T>24class 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 39public:40 typedef T (*NextAfterFunc)(T, T);41 42 void testNaN(NextAfterFunc func) {43 ASSERT_FP_EQ(func(nan, 0), nan);44 ASSERT_FP_EQ(func(0, nan), nan);45 }46 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), zero);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_H195