1 | //===-- Unittests for pow -------------------------------------------------===// |
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/fenv_macros.h" |
10 | #include "src/math/pow.h" |
11 | #include "test/UnitTest/FPMatcher.h" |
12 | #include "test/UnitTest/Test.h" |
13 | |
14 | using LlvmLibcPowTest = LIBC_NAMESPACE::testing::FPTest<double>; |
15 | using LIBC_NAMESPACE::fputil::testing::ForceRoundingMode; |
16 | using LIBC_NAMESPACE::fputil::testing::RoundingMode; |
17 | |
18 | TEST_F(LlvmLibcPowTest, SpecialNumbers) { |
19 | constexpr double NEG_ODD_INTEGER = -3.0; |
20 | constexpr double NEG_EVEN_INTEGER = -6.0; |
21 | constexpr double NEG_NON_INTEGER = -1.1; |
22 | constexpr double POS_ODD_INTEGER = 5.0; |
23 | constexpr double POS_EVEN_INTEGER = 8.0; |
24 | constexpr double POS_NON_INTEGER = 1.1; |
25 | constexpr double ONE_HALF = 0.5; |
26 | |
27 | for (int i = 0; i < N_ROUNDING_MODES; ++i) { |
28 | ForceRoundingMode __r(ROUNDING_MODES[i]); |
29 | if (!__r.success) |
30 | continue; |
31 | |
32 | // pow( sNaN, exponent ) |
33 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, sNaN), |
34 | FE_INVALID); |
35 | EXPECT_FP_EQ_WITH_EXCEPTION( |
36 | aNaN, LIBC_NAMESPACE::pow(sNaN, NEG_ODD_INTEGER), FE_INVALID); |
37 | EXPECT_FP_EQ_WITH_EXCEPTION( |
38 | aNaN, LIBC_NAMESPACE::pow(sNaN, NEG_EVEN_INTEGER), FE_INVALID); |
39 | EXPECT_FP_EQ_WITH_EXCEPTION( |
40 | aNaN, LIBC_NAMESPACE::pow(sNaN, POS_ODD_INTEGER), FE_INVALID); |
41 | EXPECT_FP_EQ_WITH_EXCEPTION( |
42 | aNaN, LIBC_NAMESPACE::pow(sNaN, POS_EVEN_INTEGER), FE_INVALID); |
43 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, ONE_HALF), |
44 | FE_INVALID); |
45 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, zero), |
46 | FE_INVALID); |
47 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, neg_zero), |
48 | FE_INVALID); |
49 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, inf), |
50 | FE_INVALID); |
51 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, neg_inf), |
52 | FE_INVALID); |
53 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(sNaN, aNaN), |
54 | FE_INVALID); |
55 | |
56 | // pow( 0.0, exponent ) |
57 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(zero, sNaN), |
58 | FE_INVALID); |
59 | EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_ODD_INTEGER), |
60 | FE_DIVBYZERO); |
61 | EXPECT_FP_EQ_WITH_EXCEPTION( |
62 | inf, LIBC_NAMESPACE::pow(zero, NEG_EVEN_INTEGER), FE_DIVBYZERO); |
63 | EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_NON_INTEGER), |
64 | FE_DIVBYZERO); |
65 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_ODD_INTEGER)); |
66 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_EVEN_INTEGER)); |
67 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_NON_INTEGER)); |
68 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, ONE_HALF)); |
69 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(zero, zero)); |
70 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(zero, neg_zero)); |
71 | EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(zero, inf)); |
72 | EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, neg_inf), |
73 | FE_DIVBYZERO); |
74 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(zero, aNaN)); |
75 | |
76 | // pow( -0.0, exponent ) |
77 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(neg_zero, sNaN), |
78 | FE_INVALID); |
79 | EXPECT_FP_EQ_WITH_EXCEPTION( |
80 | neg_inf, LIBC_NAMESPACE::pow(neg_zero, NEG_ODD_INTEGER), FE_DIVBYZERO); |
81 | EXPECT_FP_EQ_WITH_EXCEPTION( |
82 | inf, LIBC_NAMESPACE::pow(neg_zero, NEG_EVEN_INTEGER), FE_DIVBYZERO); |
83 | EXPECT_FP_EQ_WITH_EXCEPTION( |
84 | inf, LIBC_NAMESPACE::pow(neg_zero, NEG_NON_INTEGER), FE_DIVBYZERO); |
85 | EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_zero, POS_ODD_INTEGER)); |
86 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, POS_EVEN_INTEGER)); |
87 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, POS_NON_INTEGER)); |
88 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, ONE_HALF)); |
89 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_zero, zero)); |
90 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_zero, neg_zero)); |
91 | EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(neg_zero, inf)); |
92 | EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(neg_zero, neg_inf), |
93 | FE_DIVBYZERO); |
94 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_zero, aNaN)); |
95 | |
96 | // pow( 1.0, exponent ) |
97 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(1.0, sNaN), |
98 | FE_INVALID); |
99 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, zero)); |
100 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_zero)); |
101 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, 1.0)); |
102 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, -1.0)); |
103 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_ODD_INTEGER)); |
104 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_EVEN_INTEGER)); |
105 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_NON_INTEGER)); |
106 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_ODD_INTEGER)); |
107 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_EVEN_INTEGER)); |
108 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_NON_INTEGER)); |
109 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, inf)); |
110 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_inf)); |
111 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, aNaN)); |
112 | |
113 | // pow( -1.0, exponent ) |
114 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(-1.0, sNaN), |
115 | FE_INVALID); |
116 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, zero)); |
117 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_zero)); |
118 | EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, 1.0)); |
119 | EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, -1.0)); |
120 | EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, NEG_ODD_INTEGER)); |
121 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, NEG_EVEN_INTEGER)); |
122 | EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::pow(-1.0, NEG_NON_INTEGER), |
123 | FE_INVALID); |
124 | EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, POS_ODD_INTEGER)); |
125 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, POS_EVEN_INTEGER)); |
126 | EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::pow(-1.0, POS_NON_INTEGER), |
127 | FE_INVALID); |
128 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, inf)); |
129 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_inf)); |
130 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-1.0, aNaN)); |
131 | |
132 | // pow( inf, exponent ) |
133 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(inf, sNaN), |
134 | FE_INVALID); |
135 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, zero)); |
136 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, neg_zero)); |
137 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, 1.0)); |
138 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, -1.0)); |
139 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_ODD_INTEGER)); |
140 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_EVEN_INTEGER)); |
141 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_NON_INTEGER)); |
142 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_ODD_INTEGER)); |
143 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_EVEN_INTEGER)); |
144 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_NON_INTEGER)); |
145 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, ONE_HALF)); |
146 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, inf)); |
147 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, neg_inf)); |
148 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(inf, aNaN)); |
149 | |
150 | // pow( -inf, exponent ) |
151 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(neg_inf, sNaN), |
152 | FE_INVALID); |
153 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, zero)); |
154 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, neg_zero)); |
155 | EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, 1.0)); |
156 | EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_inf, -1.0)); |
157 | EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_inf, NEG_ODD_INTEGER)); |
158 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, NEG_EVEN_INTEGER)); |
159 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, NEG_NON_INTEGER)); |
160 | EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, POS_ODD_INTEGER)); |
161 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, POS_EVEN_INTEGER)); |
162 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, POS_NON_INTEGER)); |
163 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, ONE_HALF)); |
164 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, inf)); |
165 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, neg_inf)); |
166 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_inf, aNaN)); |
167 | |
168 | // pow ( aNaN, exponent ) |
169 | EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::pow(aNaN, sNaN), |
170 | FE_INVALID); |
171 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, zero)); |
172 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, neg_zero)); |
173 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, 1.0)); |
174 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, -1.0)); |
175 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_ODD_INTEGER)); |
176 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_EVEN_INTEGER)); |
177 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_NON_INTEGER)); |
178 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_ODD_INTEGER)); |
179 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_EVEN_INTEGER)); |
180 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_NON_INTEGER)); |
181 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, inf)); |
182 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, neg_inf)); |
183 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, aNaN)); |
184 | |
185 | // pow ( base, inf ) |
186 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(0.1, inf)); |
187 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(-0.1, inf)); |
188 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(1.1, inf)); |
189 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(-1.1, inf)); |
190 | |
191 | // pow ( base, -inf ) |
192 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(0.1, neg_inf)); |
193 | EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(-0.1, neg_inf)); |
194 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(1.1, neg_inf)); |
195 | EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(-1.1, neg_inf)); |
196 | |
197 | // Exact powers of 2: |
198 | // TODO: Enable these tests when we use exp2. |
199 | // EXPECT_FP_EQ(0x1.0p15, LIBC_NAMESPACE::pow(2.0, 15.0)); |
200 | // EXPECT_FP_EQ(0x1.0p126, LIBC_NAMESPACE::pow(2.0, 126.0)); |
201 | // EXPECT_FP_EQ(0x1.0p-45, LIBC_NAMESPACE::pow(2.0, -45.0)); |
202 | // EXPECT_FP_EQ(0x1.0p-126, LIBC_NAMESPACE::pow(2.0, -126.0)); |
203 | // EXPECT_FP_EQ(0x1.0p-149, LIBC_NAMESPACE::pow(2.0, -149.0)); |
204 | |
205 | // Exact powers of 10: |
206 | // TODO: Enable these tests when we use exp10 |
207 | // EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(10.0, 0.0)); |
208 | // EXPECT_FP_EQ(10.0, LIBC_NAMESPACE::pow(10.0, 1.0)); |
209 | // EXPECT_FP_EQ(100.0, LIBC_NAMESPACE::pow(10.0, 2.0)); |
210 | // EXPECT_FP_EQ(1000.0, LIBC_NAMESPACE::pow(10.0, 3.0)); |
211 | // EXPECT_FP_EQ(10000.0, LIBC_NAMESPACE::pow(10.0, 4.0)); |
212 | // EXPECT_FP_EQ(100000.0, LIBC_NAMESPACE::pow(10.0, 5.0)); |
213 | // EXPECT_FP_EQ(1000000.0, LIBC_NAMESPACE::pow(10.0, 6.0)); |
214 | // EXPECT_FP_EQ(10000000.0, LIBC_NAMESPACE::pow(10.0, 7.0)); |
215 | // EXPECT_FP_EQ(100000000.0, LIBC_NAMESPACE::pow(10.0, 8.0)); |
216 | // EXPECT_FP_EQ(1000000000.0, LIBC_NAMESPACE::pow(10.0, 9.0)); |
217 | // EXPECT_FP_EQ(10000000000.0, LIBC_NAMESPACE::pow(10.0, 10.0)); |
218 | |
219 | // Overflow / Underflow: |
220 | if (ROUNDING_MODES[i] != RoundingMode::Downward && |
221 | ROUNDING_MODES[i] != RoundingMode::TowardZero) { |
222 | EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(3.1, 2001.0), |
223 | FE_OVERFLOW); |
224 | } |
225 | if (ROUNDING_MODES[i] != RoundingMode::Upward) { |
226 | EXPECT_FP_EQ_WITH_EXCEPTION(0.0, LIBC_NAMESPACE::pow(3.1, -2001.0), |
227 | FE_UNDERFLOW); |
228 | } |
229 | } |
230 | } |
231 | |
232 | #ifdef LIBC_TEST_FTZ_DAZ |
233 | |
234 | using namespace LIBC_NAMESPACE::testing; |
235 | |
236 | TEST_F(LlvmLibcPowTest, FTZMode) { |
237 | ModifyMXCSR mxcsr(FTZ); |
238 | |
239 | EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-min_denormal, 0.5)); |
240 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal)); |
241 | } |
242 | |
243 | TEST_F(LlvmLibcPowTest, DAZMode) { |
244 | ModifyMXCSR mxcsr(DAZ); |
245 | |
246 | EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(-min_denormal, 0.5)); |
247 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal)); |
248 | } |
249 | |
250 | TEST_F(LlvmLibcPowTest, FTZDAZMode) { |
251 | ModifyMXCSR mxcsr(FTZ | DAZ); |
252 | |
253 | EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(-min_denormal, 0.5)); |
254 | EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal)); |
255 | } |
256 | |
257 | #endif |
258 | |