1*71db0c75SAndroid Build Coastguard Worker //===-- Utility class to test integer sqrt ----------------------*- C++ -*-===// 2*71db0c75SAndroid Build Coastguard Worker // 3*71db0c75SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*71db0c75SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information. 5*71db0c75SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*71db0c75SAndroid Build Coastguard Worker // 7*71db0c75SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 8*71db0c75SAndroid Build Coastguard Worker 9*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/FPMatcher.h" 10*71db0c75SAndroid Build Coastguard Worker #include "test/UnitTest/Test.h" 11*71db0c75SAndroid Build Coastguard Worker 12*71db0c75SAndroid Build Coastguard Worker #include "src/__support/CPP/bit.h" 13*71db0c75SAndroid Build Coastguard Worker #include "src/__support/FPUtil/BasicOperations.h" 14*71db0c75SAndroid Build Coastguard Worker #include "src/__support/fixed_point/fx_rep.h" 15*71db0c75SAndroid Build Coastguard Worker #include "src/__support/fixed_point/sqrt.h" 16*71db0c75SAndroid Build Coastguard Worker 17*71db0c75SAndroid Build Coastguard Worker #include "src/math/exp.h" 18*71db0c75SAndroid Build Coastguard Worker 19*71db0c75SAndroid Build Coastguard Worker template <typename T> class ExpTest : public LIBC_NAMESPACE::testing::Test { 20*71db0c75SAndroid Build Coastguard Worker 21*71db0c75SAndroid Build Coastguard Worker using FXRep = LIBC_NAMESPACE::fixed_point::FXRep<T>; 22*71db0c75SAndroid Build Coastguard Worker static constexpr T zero = FXRep::ZERO(); 23*71db0c75SAndroid Build Coastguard Worker static constexpr T one = static_cast<T>(1); 24*71db0c75SAndroid Build Coastguard Worker static constexpr T eps = FXRep::EPS(); 25*71db0c75SAndroid Build Coastguard Worker 26*71db0c75SAndroid Build Coastguard Worker public: 27*71db0c75SAndroid Build Coastguard Worker typedef T (*ExpFunc)(T); 28*71db0c75SAndroid Build Coastguard Worker test_special_numbers(ExpFunc func)29*71db0c75SAndroid Build Coastguard Worker void test_special_numbers(ExpFunc func) { 30*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(one, func(T(0))); 31*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(FXRep::MAX(), func(T(30))); 32*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(zero, func(T(-30))); 33*71db0c75SAndroid Build Coastguard Worker } 34*71db0c75SAndroid Build Coastguard Worker test_range_with_step(ExpFunc func,T step,bool rel_error)35*71db0c75SAndroid Build Coastguard Worker void test_range_with_step(ExpFunc func, T step, bool rel_error) { 36*71db0c75SAndroid Build Coastguard Worker constexpr int COUNT = 255; 37*71db0c75SAndroid Build Coastguard Worker constexpr double ERR = 3.0 * static_cast<double>(eps); 38*71db0c75SAndroid Build Coastguard Worker double x_d = 0.0; 39*71db0c75SAndroid Build Coastguard Worker T x = step; 40*71db0c75SAndroid Build Coastguard Worker for (int i = 0; i < COUNT; ++i) { 41*71db0c75SAndroid Build Coastguard Worker x += step; 42*71db0c75SAndroid Build Coastguard Worker x_d = static_cast<double>(x); 43*71db0c75SAndroid Build Coastguard Worker double y_d = static_cast<double>(func(x)); 44*71db0c75SAndroid Build Coastguard Worker double result = LIBC_NAMESPACE::exp(x_d); 45*71db0c75SAndroid Build Coastguard Worker double errors = rel_error 46*71db0c75SAndroid Build Coastguard Worker ? LIBC_NAMESPACE::fputil::abs((y_d / result) - 1.0) 47*71db0c75SAndroid Build Coastguard Worker : LIBC_NAMESPACE::fputil::abs(y_d - result); 48*71db0c75SAndroid Build Coastguard Worker if (errors > ERR) { 49*71db0c75SAndroid Build Coastguard Worker // Print out the failure input and output. 50*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(x, T(0)); 51*71db0c75SAndroid Build Coastguard Worker EXPECT_EQ(func(x), zero); 52*71db0c75SAndroid Build Coastguard Worker } 53*71db0c75SAndroid Build Coastguard Worker ASSERT_TRUE(errors <= ERR); 54*71db0c75SAndroid Build Coastguard Worker } 55*71db0c75SAndroid Build Coastguard Worker } 56*71db0c75SAndroid Build Coastguard Worker test_positive_range(ExpFunc func)57*71db0c75SAndroid Build Coastguard Worker void test_positive_range(ExpFunc func) { 58*71db0c75SAndroid Build Coastguard Worker test_range_with_step(func, T(0x1.0p-6), /*rel_error*/ true); 59*71db0c75SAndroid Build Coastguard Worker } 60*71db0c75SAndroid Build Coastguard Worker test_negative_range(ExpFunc func)61*71db0c75SAndroid Build Coastguard Worker void test_negative_range(ExpFunc func) { 62*71db0c75SAndroid Build Coastguard Worker test_range_with_step(func, T(-0x1.0p-6), /*rel_error*/ false); 63*71db0c75SAndroid Build Coastguard Worker } 64*71db0c75SAndroid Build Coastguard Worker }; 65*71db0c75SAndroid Build Coastguard Worker 66*71db0c75SAndroid Build Coastguard Worker #define LIST_EXP_TESTS(Name, T, func) \ 67*71db0c75SAndroid Build Coastguard Worker using LlvmLibcExp##Name##Test = ExpTest<T>; \ 68*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibcExp##Name##Test, SpecialNumbers) { \ 69*71db0c75SAndroid Build Coastguard Worker test_special_numbers(&func); \ 70*71db0c75SAndroid Build Coastguard Worker } \ 71*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibcExp##Name##Test, PositiveRange) { \ 72*71db0c75SAndroid Build Coastguard Worker test_positive_range(&func); \ 73*71db0c75SAndroid Build Coastguard Worker } \ 74*71db0c75SAndroid Build Coastguard Worker TEST_F(LlvmLibcExp##Name##Test, NegativeRange) { \ 75*71db0c75SAndroid Build Coastguard Worker test_negative_range(&func); \ 76*71db0c75SAndroid Build Coastguard Worker } \ 77*71db0c75SAndroid Build Coastguard Worker static_assert(true, "Require semicolon.") 78