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-exception
6//
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: x_d);
45 double errors = rel_error
46 ? LIBC_NAMESPACE::fputil::abs(x: (y_d / result) - 1.0)
47 : LIBC_NAMESPACE::fputil::abs(x: 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, step: T(0x1.0p-6), /*rel_error*/ rel_error: true);
59 }
60
61 void test_negative_range(ExpFunc func) {
62 test_range_with_step(func, step: T(-0x1.0p-6), /*rel_error*/ 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

source code of libc/test/src/stdfix/ExpTest.h