brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · 82d5378 Raw
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