1//===-- Unittests for atanhf ----------------------------------------------===//
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 "hdr/math_macros.h"
10#include "src/__support/FPUtil/FPBits.h"
11#include "src/errno/libc_errno.h"
12#include "src/math/atanhf.h"
13#include "test/UnitTest/FPMatcher.h"
14#include "test/UnitTest/Test.h"
15#include "utils/MPFRWrapper/MPFRUtils.h"
16
17#include <errno.h>
18#include <stdint.h>
19
20using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest<float>;
21
22namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
23
24TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) {
25
26 LIBC_NAMESPACE::libc_errno = 0;
27 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
28 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN));
29 EXPECT_FP_EXCEPTION(0);
30 EXPECT_MATH_ERRNO(0);
31
32 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
33 EXPECT_FP_EQ_ALL_ROUNDING(0.0f, LIBC_NAMESPACE::atanhf(0.0f));
34 EXPECT_FP_EXCEPTION(0);
35 EXPECT_MATH_ERRNO(0);
36
37 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
38 EXPECT_FP_EQ_ALL_ROUNDING(-0.0f, LIBC_NAMESPACE::atanhf(-0.0f));
39 EXPECT_FP_EXCEPTION(0);
40 EXPECT_MATH_ERRNO(0);
41
42 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
43 EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::atanhf(1.0f));
44 EXPECT_FP_EXCEPTION(FE_DIVBYZERO);
45 EXPECT_MATH_ERRNO(ERANGE);
46
47 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
48 EXPECT_FP_EQ_ALL_ROUNDING(neg_inf, LIBC_NAMESPACE::atanhf(-1.0f));
49 EXPECT_FP_EXCEPTION(FE_DIVBYZERO);
50 EXPECT_MATH_ERRNO(ERANGE);
51
52 auto bt = FPBits(1.0f);
53 bt.set_uintval(bt.uintval() + 1);
54
55 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
56 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()));
57 EXPECT_FP_EXCEPTION(FE_INVALID);
58 EXPECT_MATH_ERRNO(EDOM);
59
60 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
61 bt.set_sign(Sign::NEG);
62 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val()));
63 EXPECT_FP_EXCEPTION(FE_INVALID);
64 EXPECT_MATH_ERRNO(EDOM);
65
66 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
67 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(2.0f));
68 EXPECT_FP_EXCEPTION(FE_INVALID);
69 EXPECT_MATH_ERRNO(EDOM);
70
71 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
72 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(-2.0f));
73 EXPECT_FP_EXCEPTION(FE_INVALID);
74 EXPECT_MATH_ERRNO(EDOM);
75
76 LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT);
77 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(inf));
78 EXPECT_FP_EXCEPTION(FE_INVALID);
79 EXPECT_MATH_ERRNO(EDOM);
80
81 bt.set_sign(Sign::NEG);
82 EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(neg_inf));
83 EXPECT_FP_EXCEPTION(FE_INVALID);
84 EXPECT_MATH_ERRNO(EDOM);
85}
86
87TEST_F(LlvmLibcAtanhfTest, InFloatRange) {
88 constexpr uint32_t COUNT = 100'000;
89 const uint32_t STEP = FPBits(1.0f).uintval() / COUNT;
90 for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
91 float x = FPBits(v).get_val();
92 ASSERT_MPFR_MATCH(mpfr::Operation::Atanh, x, LIBC_NAMESPACE::atanhf(x),
93 0.5);
94 ASSERT_MPFR_MATCH(mpfr::Operation::Atanh, -x, LIBC_NAMESPACE::atanhf(-x),
95 0.5);
96 }
97}
98
99// For small values, atanh(x) is x.
100TEST_F(LlvmLibcAtanhfTest, SmallValues) {
101 float x = FPBits(uint32_t(0x17800000)).get_val();
102 float result = LIBC_NAMESPACE::atanhf(x);
103 EXPECT_MPFR_MATCH(mpfr::Operation::Atanh, x, result, 0.5);
104 EXPECT_FP_EQ(x, result);
105
106 x = FPBits(uint32_t(0x00400000)).get_val();
107 result = LIBC_NAMESPACE::atanhf(x);
108 EXPECT_MPFR_MATCH(mpfr::Operation::Atanh, x, result, 0.5);
109 EXPECT_FP_EQ(x, result);
110}
111

source code of libc/test/src/math/atanhf_test.cpp