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