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
TEST_F(LlvmLibcPowTest,SpecialNumbers)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( 0.0, exponent )
33 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_ODD_INTEGER),
34 FE_DIVBYZERO);
35 EXPECT_FP_EQ_WITH_EXCEPTION(
36 inf, LIBC_NAMESPACE::pow(zero, NEG_EVEN_INTEGER), FE_DIVBYZERO);
37 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, NEG_NON_INTEGER),
38 FE_DIVBYZERO);
39 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_ODD_INTEGER));
40 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_EVEN_INTEGER));
41 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, POS_NON_INTEGER));
42 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(zero, ONE_HALF));
43 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(zero, zero));
44 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(zero, neg_zero));
45 EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(zero, inf));
46 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(zero, neg_inf),
47 FE_DIVBYZERO);
48 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(zero, aNaN));
49
50 // pow( -0.0, exponent )
51 EXPECT_FP_EQ_WITH_EXCEPTION(
52 neg_inf, LIBC_NAMESPACE::pow(neg_zero, NEG_ODD_INTEGER), FE_DIVBYZERO);
53 EXPECT_FP_EQ_WITH_EXCEPTION(
54 inf, LIBC_NAMESPACE::pow(neg_zero, NEG_EVEN_INTEGER), FE_DIVBYZERO);
55 EXPECT_FP_EQ_WITH_EXCEPTION(
56 inf, LIBC_NAMESPACE::pow(neg_zero, NEG_NON_INTEGER), FE_DIVBYZERO);
57 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_zero, POS_ODD_INTEGER));
58 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, POS_EVEN_INTEGER));
59 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, POS_NON_INTEGER));
60 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_zero, ONE_HALF));
61 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_zero, zero));
62 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_zero, neg_zero));
63 EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(neg_zero, inf));
64 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(neg_zero, neg_inf),
65 FE_DIVBYZERO);
66 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_zero, aNaN));
67
68 // pow( 1.0, exponent )
69 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, zero));
70 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_zero));
71 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, 1.0));
72 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, -1.0));
73 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_ODD_INTEGER));
74 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_EVEN_INTEGER));
75 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, NEG_NON_INTEGER));
76 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_ODD_INTEGER));
77 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_EVEN_INTEGER));
78 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, POS_NON_INTEGER));
79 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, inf));
80 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, neg_inf));
81 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(1.0, aNaN));
82
83 // pow( 1.0, exponent )
84 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, zero));
85 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_zero));
86 EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, 1.0));
87 EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, -1.0));
88 EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, NEG_ODD_INTEGER));
89 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, NEG_EVEN_INTEGER));
90 EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::pow(-1.0, NEG_NON_INTEGER),
91 FE_INVALID);
92 EXPECT_FP_EQ(-1.0, LIBC_NAMESPACE::pow(-1.0, POS_ODD_INTEGER));
93 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, POS_EVEN_INTEGER));
94 EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::pow(-1.0, POS_NON_INTEGER),
95 FE_INVALID);
96 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, inf));
97 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(-1.0, neg_inf));
98 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-1.0, aNaN));
99
100 // pow( inf, exponent )
101 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, zero));
102 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(inf, neg_zero));
103 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, 1.0));
104 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, -1.0));
105 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_ODD_INTEGER));
106 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_EVEN_INTEGER));
107 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, NEG_NON_INTEGER));
108 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_ODD_INTEGER));
109 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_EVEN_INTEGER));
110 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, POS_NON_INTEGER));
111 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, ONE_HALF));
112 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(inf, inf));
113 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(inf, neg_inf));
114 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(inf, aNaN));
115
116 // pow( -inf, exponent )
117 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, zero));
118 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(neg_inf, neg_zero));
119 EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, 1.0));
120 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_inf, -1.0));
121 EXPECT_FP_EQ(neg_zero, LIBC_NAMESPACE::pow(neg_inf, NEG_ODD_INTEGER));
122 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, NEG_EVEN_INTEGER));
123 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, NEG_NON_INTEGER));
124 EXPECT_FP_EQ(neg_inf, LIBC_NAMESPACE::pow(neg_inf, POS_ODD_INTEGER));
125 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, POS_EVEN_INTEGER));
126 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, POS_NON_INTEGER));
127 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, ONE_HALF));
128 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(neg_inf, inf));
129 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(neg_inf, neg_inf));
130 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(neg_inf, aNaN));
131
132 // pow ( aNaN, exponent )
133 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, zero));
134 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(aNaN, neg_zero));
135 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, 1.0));
136 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, -1.0));
137 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_ODD_INTEGER));
138 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_EVEN_INTEGER));
139 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, NEG_NON_INTEGER));
140 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_ODD_INTEGER));
141 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_EVEN_INTEGER));
142 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, POS_NON_INTEGER));
143 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, inf));
144 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, neg_inf));
145 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(aNaN, aNaN));
146
147 // pow ( base, inf )
148 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(0.1, inf));
149 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(-0.1, inf));
150 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(1.1, inf));
151 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(-1.1, inf));
152
153 // pow ( base, -inf )
154 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(0.1, neg_inf));
155 EXPECT_FP_EQ(inf, LIBC_NAMESPACE::pow(-0.1, neg_inf));
156 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(1.1, neg_inf));
157 EXPECT_FP_EQ(zero, LIBC_NAMESPACE::pow(-1.1, neg_inf));
158
159 // Exact powers of 2:
160 // TODO: Enable these tests when we use exp2.
161 // EXPECT_FP_EQ(0x1.0p15, LIBC_NAMESPACE::pow(2.0, 15.0));
162 // EXPECT_FP_EQ(0x1.0p126, LIBC_NAMESPACE::pow(2.0, 126.0));
163 // EXPECT_FP_EQ(0x1.0p-45, LIBC_NAMESPACE::pow(2.0, -45.0));
164 // EXPECT_FP_EQ(0x1.0p-126, LIBC_NAMESPACE::pow(2.0, -126.0));
165 // EXPECT_FP_EQ(0x1.0p-149, LIBC_NAMESPACE::pow(2.0, -149.0));
166
167 // Exact powers of 10:
168 // TODO: Enable these tests when we use exp10
169 // EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(10.0, 0.0));
170 // EXPECT_FP_EQ(10.0, LIBC_NAMESPACE::pow(10.0, 1.0));
171 // EXPECT_FP_EQ(100.0, LIBC_NAMESPACE::pow(10.0, 2.0));
172 // EXPECT_FP_EQ(1000.0, LIBC_NAMESPACE::pow(10.0, 3.0));
173 // EXPECT_FP_EQ(10000.0, LIBC_NAMESPACE::pow(10.0, 4.0));
174 // EXPECT_FP_EQ(100000.0, LIBC_NAMESPACE::pow(10.0, 5.0));
175 // EXPECT_FP_EQ(1000000.0, LIBC_NAMESPACE::pow(10.0, 6.0));
176 // EXPECT_FP_EQ(10000000.0, LIBC_NAMESPACE::pow(10.0, 7.0));
177 // EXPECT_FP_EQ(100000000.0, LIBC_NAMESPACE::pow(10.0, 8.0));
178 // EXPECT_FP_EQ(1000000000.0, LIBC_NAMESPACE::pow(10.0, 9.0));
179 // EXPECT_FP_EQ(10000000000.0, LIBC_NAMESPACE::pow(10.0, 10.0));
180
181 // Overflow / Underflow:
182 if (ROUNDING_MODES[i] != RoundingMode::Downward &&
183 ROUNDING_MODES[i] != RoundingMode::TowardZero) {
184 EXPECT_FP_EQ_WITH_EXCEPTION(inf, LIBC_NAMESPACE::pow(3.1, 2001.0),
185 FE_OVERFLOW);
186 }
187 if (ROUNDING_MODES[i] != RoundingMode::Upward) {
188 EXPECT_FP_EQ_WITH_EXCEPTION(0.0, LIBC_NAMESPACE::pow(3.1, -2001.0),
189 FE_UNDERFLOW);
190 }
191 }
192 }
193
194 #ifdef LIBC_TEST_FTZ_DAZ
195
196 using namespace LIBC_NAMESPACE::testing;
197
TEST_F(LlvmLibcPowTest,FTZMode)198 TEST_F(LlvmLibcPowTest, FTZMode) {
199 ModifyMXCSR mxcsr(FTZ);
200
201 EXPECT_FP_IS_NAN(LIBC_NAMESPACE::pow(-min_denormal, 0.5));
202 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));
203 }
204
TEST_F(LlvmLibcPowTest,DAZMode)205 TEST_F(LlvmLibcPowTest, DAZMode) {
206 ModifyMXCSR mxcsr(DAZ);
207
208 EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(-min_denormal, 0.5));
209 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));
210 }
211
TEST_F(LlvmLibcPowTest,FTZDAZMode)212 TEST_F(LlvmLibcPowTest, FTZDAZMode) {
213 ModifyMXCSR mxcsr(FTZ | DAZ);
214
215 EXPECT_FP_EQ(0.0, LIBC_NAMESPACE::pow(-min_denormal, 0.5));
216 EXPECT_FP_EQ(1.0, LIBC_NAMESPACE::pow(2.0, min_denormal));
217 }
218
219 #endif
220