brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · d1151c8 Raw
121 lines · c
1//===-- Utility class to test frexp[f|l] ------------------------*- 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#include "src/__support/FPUtil/BasicOperations.h"10#include "test/UnitTest/FEnvSafeTest.h"11#include "test/UnitTest/FPMatcher.h"12#include "test/UnitTest/Test.h"13#include "utils/MPFRWrapper/MPFRUtils.h"14 15#include "hdr/math_macros.h"16 17namespace mpfr = LIBC_NAMESPACE::testing::mpfr;18 19template <typename T>20class FrexpTest : public LIBC_NAMESPACE::testing::FEnvSafeTest {21 22  DECLARE_SPECIAL_CONSTANTS(T)23 24  static constexpr StorageType HIDDEN_BIT =25      StorageType(1) << LIBC_NAMESPACE::fputil::FPBits<T>::FRACTION_LEN;26 27public:28  typedef T (*FrexpFunc)(T, int *);29 30  void testSpecialNumbers(FrexpFunc func) {31    int exponent;32    ASSERT_FP_EQ(aNaN, func(aNaN, &exponent));33    ASSERT_FP_EQ(inf, func(inf, &exponent));34    ASSERT_FP_EQ(neg_inf, func(neg_inf, &exponent));35 36    ASSERT_FP_EQ(zero, func(zero, &exponent));37    ASSERT_EQ(exponent, 0);38 39    ASSERT_FP_EQ(neg_zero, func(neg_zero, &exponent));40    ASSERT_EQ(exponent, 0);41  }42 43  void testPowersOfTwo(FrexpFunc func) {44    int exponent;45 46    EXPECT_FP_EQ(T(0.5), func(T(1.0), &exponent));47    EXPECT_EQ(exponent, 1);48    EXPECT_FP_EQ(T(-0.5), func(T(-1.0), &exponent));49    EXPECT_EQ(exponent, 1);50 51    EXPECT_FP_EQ(T(0.5), func(T(2.0), &exponent));52    EXPECT_EQ(exponent, 2);53    EXPECT_FP_EQ(T(-0.5), func(T(-2.0), &exponent));54    EXPECT_EQ(exponent, 2);55 56    EXPECT_FP_EQ(T(0.5), func(T(4.0), &exponent));57    EXPECT_EQ(exponent, 3);58    EXPECT_FP_EQ(T(-0.5), func(T(-4.0), &exponent));59    EXPECT_EQ(exponent, 3);60 61    EXPECT_FP_EQ(T(0.5), func(T(8.0), &exponent));62    EXPECT_EQ(exponent, 4);63    EXPECT_FP_EQ(T(-0.5), func(T(-8.0), &exponent));64    EXPECT_EQ(exponent, 4);65 66    EXPECT_FP_EQ(T(0.5), func(T(16.0), &exponent));67    EXPECT_EQ(exponent, 5);68    EXPECT_FP_EQ(T(-0.5), func(T(-16.0), &exponent));69    EXPECT_EQ(exponent, 5);70 71    EXPECT_FP_EQ(T(0.5), func(T(32.0), &exponent));72    EXPECT_EQ(exponent, 6);73    EXPECT_FP_EQ(T(-0.5), func(T(-32.0), &exponent));74    EXPECT_EQ(exponent, 6);75  }76 77  void testSomeIntegers(FrexpFunc func) {78    int exponent;79 80    EXPECT_FP_EQ(T(0.75), func(T(24.0), &exponent));81    EXPECT_EQ(exponent, 5);82    EXPECT_FP_EQ(T(-0.75), func(T(-24.0), &exponent));83    EXPECT_EQ(exponent, 5);84 85    EXPECT_FP_EQ(T(0.625), func(T(40.0), &exponent));86    EXPECT_EQ(exponent, 6);87    EXPECT_FP_EQ(T(-0.625), func(T(-40.0), &exponent));88    EXPECT_EQ(exponent, 6);89 90    EXPECT_FP_EQ(T(0.78125), func(T(800.0), &exponent));91    EXPECT_EQ(exponent, 10);92    EXPECT_FP_EQ(T(-0.78125), func(T(-800.0), &exponent));93    EXPECT_EQ(exponent, 10);94  }95 96  void testRange(FrexpFunc func) {97    using StorageType = typename FPBits::StorageType;98    constexpr StorageType COUNT = 100'000;99    constexpr StorageType STEP = STORAGE_MAX / COUNT;100    for (StorageType i = 0, v = 0; i <= COUNT; ++i, v += STEP) {101      T x = FPBits(v).get_val();102      if (FPBits(v).is_nan() || FPBits(v).is_inf() || x == 0.0l)103        continue;104 105      mpfr::BinaryOutput<T> result;106      result.f = func(x, &result.i);107 108      ASSERT_TRUE(LIBC_NAMESPACE::fputil::abs(result.f) < 1.0);109      ASSERT_TRUE(LIBC_NAMESPACE::fputil::abs(result.f) >= 0.5);110      ASSERT_MPFR_MATCH(mpfr::Operation::Frexp, x, result, 0.0);111    }112  }113};114 115#define LIST_FREXP_TESTS(T, func)                                              \116  using LlvmLibcFrexpTest = FrexpTest<T>;                                      \117  TEST_F(LlvmLibcFrexpTest, SpecialNumbers) { testSpecialNumbers(&func); }     \118  TEST_F(LlvmLibcFrexpTest, PowersOfTwo) { testPowersOfTwo(&func); }           \119  TEST_F(LlvmLibcFrexpTest, SomeIntegers) { testSomeIntegers(&func); }         \120  TEST_F(LlvmLibcFrexpTest, InRange) { testRange(&func); }121