1 | //===-- Unittests for exp2m1f ---------------------------------------------===// |
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/CPP/array.h" |
11 | #include "src/__support/FPUtil/FPBits.h" |
12 | #include "src/errno/libc_errno.h" |
13 | #include "src/math/exp2m1f.h" |
14 | #include "test/UnitTest/FPMatcher.h" |
15 | #include "test/UnitTest/Test.h" |
16 | #include "utils/MPFRWrapper/MPFRUtils.h" |
17 | |
18 | #include <stdint.h> |
19 | |
20 | using LlvmLibcExp2m1fTest = LIBC_NAMESPACE::testing::FPTest<float>; |
21 | |
22 | namespace mpfr = LIBC_NAMESPACE::testing::mpfr; |
23 | |
24 | TEST_F(LlvmLibcExp2m1fTest, TrickyInputs) { |
25 | constexpr LIBC_NAMESPACE::cpp::array<float, 10> INPUTS = { |
26 | // EXP2M1F_EXCEPTS_LO |
27 | 0x1.36dc8ep-36, |
28 | 0x1.224936p-19, |
29 | 0x1.d16d2p-20, |
30 | 0x1.17949ep-14, |
31 | -0x1.9c3e1ep-38, |
32 | -0x1.4d89b4p-32, |
33 | -0x1.a6eac4p-10, |
34 | -0x1.e7526ep-6, |
35 | // EXP2M1F_EXCEPTS_HI |
36 | 0x1.16a972p-1, |
37 | -0x1.9f12acp-5, |
38 | }; |
39 | |
40 | for (float x : INPUTS) { |
41 | LIBC_NAMESPACE::libc_errno = 0; |
42 | EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2m1, x, |
43 | LIBC_NAMESPACE::exp2m1f(x), 0.5); |
44 | } |
45 | } |
46 | |
47 | TEST_F(LlvmLibcExp2m1fTest, InFloatRange) { |
48 | constexpr uint32_t COUNT = 100'000; |
49 | constexpr uint32_t STEP = UINT32_MAX / COUNT; |
50 | for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) { |
51 | float x = FPBits(v).get_val(); |
52 | if (isnan(x: x) || isinf(x: x)) |
53 | continue; |
54 | LIBC_NAMESPACE::libc_errno = 0; |
55 | float result = LIBC_NAMESPACE::exp2m1f(x); |
56 | |
57 | // If the computation resulted in an error or did not produce valid result |
58 | // in the single-precision floating point range, then ignore comparing with |
59 | // MPFR result as MPFR can still produce valid results because of its |
60 | // wider precision. |
61 | if (isnan(x: result) || isinf(x: result) || LIBC_NAMESPACE::libc_errno != 0) |
62 | continue; |
63 | ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Exp2m1, x, |
64 | LIBC_NAMESPACE::exp2m1f(x), 0.5); |
65 | } |
66 | } |
67 | |