1 //===-- Unittests for expm1f-----------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "src/__support/FPUtil/FPBits.h"
10 #include "src/errno/libc_errno.h"
11 #include "src/math/expm1f.h"
12 #include "test/UnitTest/FPMatcher.h"
13 #include "test/UnitTest/Test.h"
14 #include "utils/MPFRWrapper/MPFRUtils.h"
19 using LlvmLibcExpm1fTest
= LIBC_NAMESPACE::testing::FPTest
<float>;
21 namespace mpfr
= LIBC_NAMESPACE::testing::mpfr
;
23 TEST_F(LlvmLibcExpm1fTest
, SpecialNumbers
) {
26 EXPECT_FP_EQ(aNaN
, LIBC_NAMESPACE::expm1f(aNaN
));
29 EXPECT_FP_EQ(inf
, LIBC_NAMESPACE::expm1f(inf
));
32 EXPECT_FP_EQ(-1.0f
, LIBC_NAMESPACE::expm1f(neg_inf
));
35 EXPECT_FP_EQ(0.0f
, LIBC_NAMESPACE::expm1f(0.0f
));
38 EXPECT_FP_EQ(-0.0f
, LIBC_NAMESPACE::expm1f(-0.0f
));
42 TEST_F(LlvmLibcExpm1fTest
, Overflow
) {
44 EXPECT_FP_EQ_WITH_EXCEPTION(
45 inf
, LIBC_NAMESPACE::expm1f(float(FPBits(0x7f7fffffU
))), FE_OVERFLOW
);
46 EXPECT_MATH_ERRNO(ERANGE
);
48 EXPECT_FP_EQ_WITH_EXCEPTION(
49 inf
, LIBC_NAMESPACE::expm1f(float(FPBits(0x42cffff8U
))), FE_OVERFLOW
);
50 EXPECT_MATH_ERRNO(ERANGE
);
52 EXPECT_FP_EQ_WITH_EXCEPTION(
53 inf
, LIBC_NAMESPACE::expm1f(float(FPBits(0x42d00008U
))), FE_OVERFLOW
);
54 EXPECT_MATH_ERRNO(ERANGE
);
57 TEST_F(LlvmLibcExpm1fTest
, Underflow
) {
59 EXPECT_FP_EQ(-1.0f
, LIBC_NAMESPACE::expm1f(float(FPBits(0xff7fffffU
))));
61 float x
= float(FPBits(0xc2cffff8U
));
62 EXPECT_FP_EQ(-1.0f
, LIBC_NAMESPACE::expm1f(x
));
64 x
= float(FPBits(0xc2d00008U
));
65 EXPECT_FP_EQ(-1.0f
, LIBC_NAMESPACE::expm1f(x
));
68 // Test with inputs which are the borders of underflow/overflow but still
69 // produce valid results without setting errno.
70 TEST_F(LlvmLibcExpm1fTest
, Borderline
) {
74 x
= float(FPBits(0x42affff8U
));
75 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
76 LIBC_NAMESPACE::expm1f(x
), 0.5);
79 x
= float(FPBits(0x42b00008U
));
80 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
81 LIBC_NAMESPACE::expm1f(x
), 0.5);
84 x
= float(FPBits(0xc2affff8U
));
85 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
86 LIBC_NAMESPACE::expm1f(x
), 0.5);
89 x
= float(FPBits(0xc2b00008U
));
90 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
91 LIBC_NAMESPACE::expm1f(x
), 0.5);
94 x
= float(FPBits(0x3dc252ddU
));
95 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
96 LIBC_NAMESPACE::expm1f(x
), 0.5);
99 x
= float(FPBits(0x3e35bec5U
));
100 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
101 LIBC_NAMESPACE::expm1f(x
), 0.5);
102 EXPECT_MATH_ERRNO(0);
104 x
= float(FPBits(0x942ed494U
));
105 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
106 LIBC_NAMESPACE::expm1f(x
), 0.5);
107 EXPECT_MATH_ERRNO(0);
109 x
= float(FPBits(0xbdc1c6cbU
));
110 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
111 LIBC_NAMESPACE::expm1f(x
), 0.5);
112 EXPECT_MATH_ERRNO(0);
115 TEST_F(LlvmLibcExpm1fTest
, InFloatRange
) {
116 constexpr uint32_t COUNT
= 100'000;
117 constexpr uint32_t STEP
= UINT32_MAX
/ COUNT
;
118 for (uint32_t i
= 0, v
= 0; i
<= COUNT
; ++i
, v
+= STEP
) {
119 float x
= float(FPBits(v
));
120 if (isnan(x
) || isinf(x
))
123 float result
= LIBC_NAMESPACE::expm1f(x
);
125 // If the computation resulted in an error or did not produce valid result
126 // in the single-precision floating point range, then ignore comparing with
127 // MPFR result as MPFR can still produce valid results because of its
129 if (isnan(result
) || isinf(result
) || libc_errno
!= 0)
131 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
132 LIBC_NAMESPACE::expm1f(x
), 0.5);