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/math/expm1f.h"
11 #include "test/UnitTest/FPMatcher.h"
12 #include "test/UnitTest/Test.h"
13 #include "utils/MPFRWrapper/MPFRUtils.h"
19 namespace mpfr
= __llvm_libc::testing::mpfr
;
21 DECLARE_SPECIAL_CONSTANTS(float)
23 TEST(LlvmLibcExpm1fTest
, SpecialNumbers
) {
26 EXPECT_FP_EQ(aNaN
, __llvm_libc::expm1f(aNaN
));
29 EXPECT_FP_EQ(inf
, __llvm_libc::expm1f(inf
));
32 EXPECT_FP_EQ(-1.0f
, __llvm_libc::expm1f(neg_inf
));
35 EXPECT_FP_EQ(0.0f
, __llvm_libc::expm1f(0.0f
));
38 EXPECT_FP_EQ(-0.0f
, __llvm_libc::expm1f(-0.0f
));
42 TEST(LlvmLibcExpm1fTest
, Overflow
) {
44 EXPECT_FP_EQ(inf
, __llvm_libc::expm1f(float(FPBits(0x7f7fffffU
))));
45 EXPECT_MATH_ERRNO(ERANGE
);
47 EXPECT_FP_EQ(inf
, __llvm_libc::expm1f(float(FPBits(0x42cffff8U
))));
48 EXPECT_MATH_ERRNO(ERANGE
);
50 EXPECT_FP_EQ(inf
, __llvm_libc::expm1f(float(FPBits(0x42d00008U
))));
51 EXPECT_MATH_ERRNO(ERANGE
);
54 TEST(LlvmLibcExpm1fTest
, Underflow
) {
56 EXPECT_FP_EQ(-1.0f
, __llvm_libc::expm1f(float(FPBits(0xff7fffffU
))));
58 float x
= float(FPBits(0xc2cffff8U
));
59 EXPECT_FP_EQ(-1.0f
, __llvm_libc::expm1f(x
));
61 x
= float(FPBits(0xc2d00008U
));
62 EXPECT_FP_EQ(-1.0f
, __llvm_libc::expm1f(x
));
65 // Test with inputs which are the borders of underflow/overflow but still
66 // produce valid results without setting errno.
67 TEST(LlvmLibcExpm1fTest
, Borderline
) {
71 x
= float(FPBits(0x42affff8U
));
72 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
73 __llvm_libc::expm1f(x
), 0.5);
76 x
= float(FPBits(0x42b00008U
));
77 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
78 __llvm_libc::expm1f(x
), 0.5);
81 x
= float(FPBits(0xc2affff8U
));
82 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
83 __llvm_libc::expm1f(x
), 0.5);
86 x
= float(FPBits(0xc2b00008U
));
87 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
88 __llvm_libc::expm1f(x
), 0.5);
91 x
= float(FPBits(0x3dc252ddU
));
92 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
93 __llvm_libc::expm1f(x
), 0.5);
96 x
= float(FPBits(0x3e35bec5U
));
97 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
98 __llvm_libc::expm1f(x
), 0.5);
101 x
= float(FPBits(0x942ed494U
));
102 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
103 __llvm_libc::expm1f(x
), 0.5);
104 EXPECT_MATH_ERRNO(0);
106 x
= float(FPBits(0xbdc1c6cbU
));
107 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
108 __llvm_libc::expm1f(x
), 0.5);
109 EXPECT_MATH_ERRNO(0);
112 TEST(LlvmLibcExpm1fTest
, InFloatRange
) {
113 constexpr uint32_t COUNT
= 1000000;
114 constexpr uint32_t STEP
= UINT32_MAX
/ COUNT
;
115 for (uint32_t i
= 0, v
= 0; i
<= COUNT
; ++i
, v
+= STEP
) {
116 float x
= float(FPBits(v
));
117 if (isnan(x
) || isinf(x
))
120 float result
= __llvm_libc::expm1f(x
);
122 // If the computation resulted in an error or did not produce valid result
123 // in the single-precision floating point range, then ignore comparing with
124 // MPFR result as MPFR can still produce valid results because of its
126 if (isnan(result
) || isinf(result
) || errno
!= 0)
128 ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Expm1
, x
,
129 __llvm_libc::expm1f(x
), 0.5);