blob: 4baad3fc9ad0ebd16d3cc815005356a707bd484f [file] [log] [blame]
Michael Kruse54f37132025-02-16 13:25:31 +01001//===-- unittests/Runtime/Numeric.cpp ---------------------------*- C++ -*-===//
peter klausler5f6c5c62021-04-01 12:59:59 -07002//
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
Peter Klausler830c0b92021-09-01 16:00:53 -07009#include "flang/Runtime/numeric.h"
peter klausler5f6c5c62021-04-01 12:59:59 -070010#include "gtest/gtest.h"
Peter Steinfeld478e0b52023-07-17 12:21:01 -070011#include "flang/Common/float128.h"
peter klausler5f6c5c62021-04-01 12:59:59 -070012#include <cmath>
13#include <limits>
14
15using namespace Fortran::runtime;
16using Fortran::common::TypeCategory;
17template <int KIND> using Int = CppTypeFor<TypeCategory::Integer, KIND>;
18template <int KIND> using Real = CppTypeFor<TypeCategory::Real, KIND>;
19
20// Simple tests of numeric intrinsic functions using examples from Fortran 2018
21
peter klausler5f6c5c62021-04-01 12:59:59 -070022TEST(Numeric, Ceiling) {
23 EXPECT_EQ(RTNAME(Ceiling4_4)(Real<4>{3.7}), 4);
24 EXPECT_EQ(RTNAME(Ceiling8_8)(Real<8>{-3.7}), -3);
25 EXPECT_EQ(RTNAME(Ceiling4_1)(Real<4>{0}), 0);
peter klausler5f6c5c62021-04-01 12:59:59 -070026}
27
28TEST(Numeric, Floor) {
29 EXPECT_EQ(RTNAME(Floor4_4)(Real<4>{3.7}), 3);
30 EXPECT_EQ(RTNAME(Floor8_8)(Real<8>{-3.7}), -4);
31 EXPECT_EQ(RTNAME(Floor4_1)(Real<4>{0}), 0);
peter klausler5f6c5c62021-04-01 12:59:59 -070032}
33
David Parksa03e93e2024-06-11 10:40:00 -060034TEST(Numeric, Erfc_scaled) {
35 EXPECT_NEAR(RTNAME(ErfcScaled4)(Real<4>{20.0}), 0.02817434874, 1.0e-8);
36 EXPECT_NEAR(RTNAME(ErfcScaled8)(Real<8>{20.0}), 0.02817434874, 1.0e-11);
Slava Zakharin104f3c12024-09-18 17:41:33 -070037#if HAS_FLOAT80
David Parksa03e93e2024-06-11 10:40:00 -060038 EXPECT_NEAR(RTNAME(ErfcScaled10)(Real<10>{20.0}), 0.02817434874, 1.0e-8);
39#endif
40}
41
peter klausler5f6c5c62021-04-01 12:59:59 -070042TEST(Numeric, Exponent) {
43 EXPECT_EQ(RTNAME(Exponent4_4)(Real<4>{0}), 0);
44 EXPECT_EQ(RTNAME(Exponent4_8)(Real<4>{1.0}), 1);
45 EXPECT_EQ(RTNAME(Exponent8_4)(Real<8>{4.1}), 3);
46 EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::infinity()),
47 std::numeric_limits<Int<8>>::max());
48 EXPECT_EQ(RTNAME(Exponent8_8)(std::numeric_limits<Real<8>>::quiet_NaN()),
49 std::numeric_limits<Int<8>>::max());
50}
51
52TEST(Numeric, Fraction) {
53 EXPECT_EQ(RTNAME(Fraction4)(Real<4>{0}), 0);
54 EXPECT_EQ(RTNAME(Fraction8)(Real<8>{3.0}), 0.75);
55 EXPECT_TRUE(
56 std::isnan(RTNAME(Fraction4)(std::numeric_limits<Real<4>>::infinity())));
57 EXPECT_TRUE(
58 std::isnan(RTNAME(Fraction8)(std::numeric_limits<Real<8>>::quiet_NaN())));
59}
60
peter klausler71d868c2021-04-15 14:11:47 -070061TEST(Numeric, IsNaN) {
62 EXPECT_FALSE(RTNAME(IsNaN4)(Real<4>{0}));
63 EXPECT_FALSE(RTNAME(IsNaN8)(std::numeric_limits<Real<8>>::infinity()));
64 EXPECT_TRUE(RTNAME(IsNaN8)(std::numeric_limits<Real<8>>::quiet_NaN()));
65}
66
peter klausler5f6c5c62021-04-01 12:59:59 -070067TEST(Numeric, Mod) {
68 EXPECT_EQ(RTNAME(ModInteger1)(Int<1>{8}, Int<1>(5)), 3);
69 EXPECT_EQ(RTNAME(ModInteger4)(Int<4>{-8}, Int<4>(5)), -3);
70 EXPECT_EQ(RTNAME(ModInteger2)(Int<2>{8}, Int<2>(-5)), 3);
71 EXPECT_EQ(RTNAME(ModInteger8)(Int<8>{-8}, Int<8>(-5)), -3);
72 EXPECT_EQ(RTNAME(ModReal4)(Real<4>{8.0}, Real<4>(5.0)), 3.0);
73 EXPECT_EQ(RTNAME(ModReal4)(Real<4>{-8.0}, Real<4>(5.0)), -3.0);
74 EXPECT_EQ(RTNAME(ModReal8)(Real<8>{8.0}, Real<8>(-5.0)), 3.0);
75 EXPECT_EQ(RTNAME(ModReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0);
Slava Zakharin315c88c52024-04-03 10:19:06 -070076 EXPECT_EQ(
77 RTNAME(ModReal4)(Real<4>{0.5}, std::numeric_limits<Real<4>>::infinity()),
78 0.5);
79 EXPECT_EQ(
80 RTNAME(ModReal4)(Real<4>{-0.5}, std::numeric_limits<Real<4>>::infinity()),
81 -0.5);
82 EXPECT_EQ(
83 RTNAME(ModReal4)(Real<4>{0.5}, -std::numeric_limits<Real<4>>::infinity()),
84 0.5);
85 EXPECT_EQ(RTNAME(ModReal4)(
86 Real<4>{-0.5}, -std::numeric_limits<Real<4>>::infinity()),
87 -0.5);
88 EXPECT_EQ(
89 RTNAME(ModReal8)(Real<8>{0.5}, std::numeric_limits<Real<8>>::infinity()),
90 0.5);
91 EXPECT_EQ(
92 RTNAME(ModReal8)(Real<8>{-0.5}, std::numeric_limits<Real<8>>::infinity()),
93 -0.5);
94 EXPECT_EQ(
95 RTNAME(ModReal8)(Real<8>{0.5}, -std::numeric_limits<Real<8>>::infinity()),
96 0.5);
97 EXPECT_EQ(RTNAME(ModReal8)(
98 Real<8>{-0.5}, -std::numeric_limits<Real<8>>::infinity()),
99 -0.5);
peter klausler5f6c5c62021-04-01 12:59:59 -0700100}
101
102TEST(Numeric, Modulo) {
103 EXPECT_EQ(RTNAME(ModuloInteger1)(Int<1>{8}, Int<1>(5)), 3);
104 EXPECT_EQ(RTNAME(ModuloInteger4)(Int<4>{-8}, Int<4>(5)), 2);
105 EXPECT_EQ(RTNAME(ModuloInteger2)(Int<2>{8}, Int<2>(-5)), -2);
106 EXPECT_EQ(RTNAME(ModuloInteger8)(Int<8>{-8}, Int<8>(-5)), -3);
107 EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{8.0}, Real<4>(5.0)), 3.0);
108 EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-8.0}, Real<4>(5.0)), 2.0);
109 EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{8.0}, Real<8>(-5.0)), -2.0);
110 EXPECT_EQ(RTNAME(ModuloReal8)(Real<8>{-8.0}, Real<8>(-5.0)), -3.0);
Slava Zakharin315c88c52024-04-03 10:19:06 -0700111 // MODULO(x, INF) == NaN
112 EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
113 Real<4>{0.5}, std::numeric_limits<Real<4>>::infinity())));
114 EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
115 Real<4>{-0.5}, std::numeric_limits<Real<4>>::infinity())));
116 EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
117 Real<4>{0.5}, -std::numeric_limits<Real<4>>::infinity())));
118 EXPECT_TRUE(std::isnan(RTNAME(ModuloReal4)(
119 Real<4>{-0.5}, -std::numeric_limits<Real<4>>::infinity())));
120 EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
121 Real<8>{-0.5}, std::numeric_limits<Real<8>>::infinity())));
122 EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
123 Real<8>{0.5}, std::numeric_limits<Real<8>>::infinity())));
124 EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
125 Real<8>{-0.5}, -std::numeric_limits<Real<8>>::infinity())));
126 EXPECT_TRUE(std::isnan(RTNAME(ModuloReal8)(
127 Real<8>{0.5}, -std::numeric_limits<Real<8>>::infinity())));
128 // MODULO(x, y) for integer values of x and y with 0 remainder.
129 EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{5.0}, Real<4>(1.0)), 0.0);
130 EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{5.0}, Real<4>(-1.0)), -0.0);
131 EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-5.0}, Real<4>(1.0)), 0.0);
132 EXPECT_EQ(RTNAME(ModuloReal4)(Real<4>{-5.0}, Real<4>(-1.0)), -0.0);
peter klausler5f6c5c62021-04-01 12:59:59 -0700133}
134
135TEST(Numeric, Nearest) {
136 EXPECT_EQ(RTNAME(Nearest4)(Real<4>{0}, true),
137 std::numeric_limits<Real<4>>::denorm_min());
138 EXPECT_EQ(RTNAME(Nearest4)(Real<4>{3.0}, true),
139 Real<4>{3.0} + std::ldexp(Real<4>{1.0}, -22));
140 EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, true),
141 Real<8>{1.0} + std::ldexp(Real<8>{1.0}, -52));
142 EXPECT_EQ(RTNAME(Nearest8)(Real<8>{1.0}, false),
Peter Klausler39c2f592023-12-26 15:28:36 -0800143 Real<8>{1.0} - 0.5 * std::ldexp(Real<8>{1.0}, -52));
peter klausler5f6c5c62021-04-01 12:59:59 -0700144}
145
146TEST(Numeric, Nint) {
147 EXPECT_EQ(RTNAME(Nint4_4)(Real<4>{2.783}), 3);
148 EXPECT_EQ(RTNAME(Nint8_4)(Real<8>{-2.783}), -3);
149 EXPECT_EQ(RTNAME(Nint4_4)(Real<4>{2.5}), 3);
150 EXPECT_EQ(RTNAME(Nint8_4)(Real<8>{-2.5}), -3);
151 EXPECT_EQ(RTNAME(Nint8_8)(Real<8>{0}), 0);
peter klausler5f6c5c62021-04-01 12:59:59 -0700152}
153
154TEST(Numeric, RRSpacing) {
155 EXPECT_EQ(RTNAME(RRSpacing8)(Real<8>{0}), 0);
156 EXPECT_EQ(RTNAME(RRSpacing4)(Real<4>{-3.0}), 0.75 * (1 << 24));
157 EXPECT_EQ(RTNAME(RRSpacing8)(Real<8>{-3.0}), 0.75 * (std::int64_t{1} << 53));
158 EXPECT_TRUE(
159 std::isnan(RTNAME(RRSpacing4)(std::numeric_limits<Real<4>>::infinity())));
160 EXPECT_TRUE(std::isnan(
161 RTNAME(RRSpacing8)(std::numeric_limits<Real<8>>::quiet_NaN())));
162}
163
164TEST(Numeric, Scale) {
165 EXPECT_EQ(RTNAME(Scale4)(Real<4>{0}, 0), 0);
166 EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, 0), 1.0);
167 EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, 1), 2.0);
168 EXPECT_EQ(RTNAME(Scale4)(Real<4>{1.0}, -1), 0.5);
169 EXPECT_TRUE(
170 std::isinf(RTNAME(Scale4)(std::numeric_limits<Real<4>>::infinity(), 1)));
171 EXPECT_TRUE(
172 std::isnan(RTNAME(Scale8)(std::numeric_limits<Real<8>>::quiet_NaN(), 1)));
173}
174
175TEST(Numeric, SetExponent) {
176 EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{0}, 0), 0);
177 EXPECT_EQ(RTNAME(SetExponent8)(Real<8>{0}, 666), 0);
peter klauslera05bae62021-08-12 11:10:53 -0700178 EXPECT_EQ(RTNAME(SetExponent8)(Real<8>{3.0}, 0), 0.75);
179 EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, 0), 0.5);
180 EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, 1), 1.0);
181 EXPECT_EQ(RTNAME(SetExponent4)(Real<4>{1.0}, -1), 0.25);
peter klausler5f6c5c62021-04-01 12:59:59 -0700182 EXPECT_TRUE(std::isnan(
183 RTNAME(SetExponent4)(std::numeric_limits<Real<4>>::infinity(), 1)));
184 EXPECT_TRUE(std::isnan(
185 RTNAME(SetExponent8)(std::numeric_limits<Real<8>>::quiet_NaN(), 1)));
186}
187
Peixin Qiaof532c072022-07-26 00:33:27 +0800188TEST(Numeric, SelectedIntKind) {
189 std::int8_t r0 = 1;
190 std::int16_t r1 = 3;
191 std::int32_t r2 = 8;
192 std::int64_t r3 = 10;
193 std::int32_t r4 = -10;
194 std::int32_t r5 = 100;
195 EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r0, 1), 1);
196 EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r1, 2), 2);
197 EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r2, 4), 4);
198 EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r3, 8), 8);
199 EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r4, 4), 1);
200 EXPECT_EQ(RTNAME(SelectedIntKind)(__FILE__, __LINE__, &r5, 4), -1);
201}
202
Peixin Qiao57e3fa32022-07-25 19:36:14 +0800203TEST(Numeric, SelectedRealKind) {
204 std::int8_t p_s = 1;
205 std::int16_t p[11] = {-10, 1, 1, 4, 50, 1, 1, 4, 1, 1, 50};
206 std::int32_t r[11] = {-1, 1, 1, 1, 2, 1, 20, 20, 100, 5000, 5000};
207 std::int64_t d[11] = {2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2};
208 EXPECT_EQ(RTNAME(SelectedRealKind)(
209 __FILE__, __LINE__, &p[0], 2, &r[0], 4, &d[0], 8),
210 2);
211 EXPECT_EQ(RTNAME(SelectedRealKind)(
212 __FILE__, __LINE__, &p[1], 2, &r[1], 4, &d[1], 8),
213 -5);
214 EXPECT_EQ(RTNAME(SelectedRealKind)(
215 __FILE__, __LINE__, &p[2], 2, &r[2], 4, &d[2], 8),
216 2);
217 EXPECT_EQ(RTNAME(SelectedRealKind)(
218 __FILE__, __LINE__, &p[3], 2, &r[3], 4, &d[3], 8),
219 4);
220 EXPECT_EQ(RTNAME(SelectedRealKind)(
221 __FILE__, __LINE__, &p[4], 2, &r[4], 4, &d[4], 8),
222 -1);
223 EXPECT_EQ(RTNAME(SelectedRealKind)(
224 __FILE__, __LINE__, &p[5], 2, &r[5], 4, &d[5], 8),
225 2);
226 EXPECT_EQ(RTNAME(SelectedRealKind)(
227 __FILE__, __LINE__, &p[6], 2, &r[6], 4, &d[6], 8),
228 3);
229 EXPECT_EQ(RTNAME(SelectedRealKind)(
230 __FILE__, __LINE__, &p[7], 2, &r[7], 4, &d[7], 8),
231 4);
232 EXPECT_EQ(RTNAME(SelectedRealKind)(
233 __FILE__, __LINE__, &p[8], 2, &r[8], 4, &d[8], 8),
234 8);
235 EXPECT_EQ(RTNAME(SelectedRealKind)(
236 __FILE__, __LINE__, &p[9], 2, &r[9], 4, &d[9], 8),
237 -2);
238 EXPECT_EQ(RTNAME(SelectedRealKind)(
239 __FILE__, __LINE__, &p[10], 2, &r[10], 4, &d[10], 8),
240 -3);
241 EXPECT_EQ(
242 RTNAME(SelectedRealKind)(__FILE__, __LINE__, &p_s, 1, &r[0], 4, &d[0], 8),
243 2);
244 EXPECT_EQ(RTNAME(SelectedRealKind)(
245 __FILE__, __LINE__, nullptr, 0, &r[0], 4, &d[0], 8),
246 2);
247 EXPECT_EQ(RTNAME(SelectedRealKind)(
248 __FILE__, __LINE__, &p[0], 2, nullptr, 0, &d[0], 8),
249 2);
250 EXPECT_EQ(RTNAME(SelectedRealKind)(
251 __FILE__, __LINE__, &p[0], 2, &r[0], 4, nullptr, 0),
252 2);
253}
254
peter klausler5f6c5c62021-04-01 12:59:59 -0700255TEST(Numeric, Spacing) {
256 EXPECT_EQ(RTNAME(Spacing8)(Real<8>{0}), std::numeric_limits<Real<8>>::min());
257 EXPECT_EQ(RTNAME(Spacing4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -22));
258 EXPECT_TRUE(
259 std::isnan(RTNAME(Spacing4)(std::numeric_limits<Real<4>>::infinity())));
260 EXPECT_TRUE(
261 std::isnan(RTNAME(Spacing8)(std::numeric_limits<Real<8>>::quiet_NaN())));
Peter Klausler500f6cc2024-09-04 10:53:22 -0700262 EXPECT_EQ(RTNAME(Spacing2By4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -9));
263 EXPECT_EQ(RTNAME(Spacing2By4)(Real<4>{0.0}), Real<4>{0.00006103515625E-04});
264 EXPECT_EQ(RTNAME(Spacing3By4)(Real<4>{3.0}), std::ldexp(Real<4>{1.0}, -6));
265 EXPECT_EQ(
266 RTNAME(Spacing3By4)(Real<4>{0.0}), std::numeric_limits<Real<4>>::min());
peter klausler5f6c5c62021-04-01 12:59:59 -0700267}
Slava Zakharin9e8f6772022-12-14 10:22:00 -0800268
269TEST(Numeric, FPowI) {
270 EXPECT_EQ(RTNAME(FPow4i)(Real<4>{0}, Int<4>{0}), Real<4>{1});
271 EXPECT_EQ(RTNAME(FPow4i)(Real<4>{0.3}, Int<4>{0}), Real<4>{1});
272 EXPECT_EQ(RTNAME(FPow4i)(Real<4>{2}, Int<4>{-1}), Real<4>{0.5});
273 EXPECT_EQ(RTNAME(FPow4i)(Real<4>{0.5}, Int<4>{-1}), Real<4>{2});
274 EXPECT_EQ(RTNAME(FPow4i)(Real<4>{-3}, Int<4>{3}), Real<4>{-27});
275 EXPECT_EQ(RTNAME(FPow4i)(Real<4>{-2}, Int<4>{-3}), Real<4>{-0.125});
276
277 EXPECT_EQ(RTNAME(FPow4k)(Real<4>{0}, Int<8>{0}), Real<4>{1});
278 EXPECT_EQ(RTNAME(FPow4k)(Real<4>{0.3}, Int<8>{0}), Real<4>{1});
279 EXPECT_EQ(RTNAME(FPow4k)(Real<4>{2}, Int<8>{-1}), Real<4>{0.5});
280 EXPECT_EQ(RTNAME(FPow4k)(Real<4>{0.5}, Int<8>{-1}), Real<4>{2});
281 EXPECT_EQ(RTNAME(FPow4k)(Real<4>{-3}, Int<8>{3}), Real<4>{-27});
282 EXPECT_EQ(RTNAME(FPow4k)(Real<4>{-2}, Int<8>{-3}), Real<4>{-0.125});
283
284 EXPECT_EQ(RTNAME(FPow8i)(Real<8>{0}, Int<4>{0}), Real<8>{1});
285 EXPECT_EQ(RTNAME(FPow8i)(Real<8>{0.3}, Int<4>{0}), Real<8>{1});
286 EXPECT_EQ(RTNAME(FPow8i)(Real<8>{2}, Int<4>{-1}), Real<8>{0.5});
287 EXPECT_EQ(RTNAME(FPow8i)(Real<8>{0.5}, Int<4>{-1}), Real<8>{2});
288 EXPECT_EQ(RTNAME(FPow8i)(Real<8>{-3}, Int<4>{3}), Real<8>{-27});
289 EXPECT_EQ(RTNAME(FPow8i)(Real<8>{-2}, Int<4>{-3}), Real<8>{-0.125});
290
291 EXPECT_EQ(RTNAME(FPow8k)(Real<8>{0}, Int<8>{0}), Real<8>{1});
292 EXPECT_EQ(RTNAME(FPow8k)(Real<8>{0.3}, Int<8>{0}), Real<8>{1});
293 EXPECT_EQ(RTNAME(FPow8k)(Real<8>{2}, Int<8>{-1}), Real<8>{0.5});
294 EXPECT_EQ(RTNAME(FPow8k)(Real<8>{0.5}, Int<8>{-1}), Real<8>{2});
295 EXPECT_EQ(RTNAME(FPow8k)(Real<8>{-3}, Int<8>{3}), Real<8>{-27});
296 EXPECT_EQ(RTNAME(FPow8k)(Real<8>{-2}, Int<8>{-3}), Real<8>{-0.125});
297
Slava Zakharin104f3c12024-09-18 17:41:33 -0700298#if HAS_FLOAT80
Slava Zakharin9e8f6772022-12-14 10:22:00 -0800299 EXPECT_EQ(RTNAME(FPow10i)(Real<10>{0}, Int<4>{0}), Real<10>{1});
300 EXPECT_EQ(RTNAME(FPow10i)(Real<10>{0.3}, Int<4>{0}), Real<10>{1});
301 EXPECT_EQ(RTNAME(FPow10i)(Real<10>{2}, Int<4>{-1}), Real<10>{0.5});
302 EXPECT_EQ(RTNAME(FPow10i)(Real<10>{0.5}, Int<4>{-1}), Real<10>{2});
303 EXPECT_EQ(RTNAME(FPow10i)(Real<10>{-3}, Int<4>{3}), Real<10>{-27});
304 EXPECT_EQ(RTNAME(FPow10i)(Real<10>{-2}, Int<4>{-3}), Real<10>{-0.125});
305
306 EXPECT_EQ(RTNAME(FPow10k)(Real<10>{0}, Int<8>{0}), Real<10>{1});
307 EXPECT_EQ(RTNAME(FPow10k)(Real<10>{0.3}, Int<8>{0}), Real<10>{1});
308 EXPECT_EQ(RTNAME(FPow10k)(Real<10>{2}, Int<8>{-1}), Real<10>{0.5});
309 EXPECT_EQ(RTNAME(FPow10k)(Real<10>{0.5}, Int<8>{-1}), Real<10>{2});
310 EXPECT_EQ(RTNAME(FPow10k)(Real<10>{-3}, Int<8>{3}), Real<10>{-27});
311 EXPECT_EQ(RTNAME(FPow10k)(Real<10>{-2}, Int<8>{-3}), Real<10>{-0.125});
312#endif
Slava Zakharinfc51c7f2024-09-19 15:45:45 -0700313#if HAS_LDBL128 || HAS_FLOAT128
Slava Zakharin9e8f6772022-12-14 10:22:00 -0800314 EXPECT_EQ(RTNAME(FPow16i)(Real<16>{0}, Int<4>{0}), Real<16>{1});
315 EXPECT_EQ(RTNAME(FPow16i)(Real<16>{0.3}, Int<4>{0}), Real<16>{1});
316 EXPECT_EQ(RTNAME(FPow16i)(Real<16>{2}, Int<4>{-1}), Real<16>{0.5});
317 EXPECT_EQ(RTNAME(FPow16i)(Real<16>{0.5}, Int<4>{-1}), Real<16>{2});
318 EXPECT_EQ(RTNAME(FPow16i)(Real<16>{-3}, Int<4>{3}), Real<16>{-27});
319 EXPECT_EQ(RTNAME(FPow16i)(Real<16>{-2}, Int<4>{-3}), Real<16>{-0.125});
320
321 EXPECT_EQ(RTNAME(FPow16k)(Real<16>{0}, Int<8>{0}), Real<16>{1});
322 EXPECT_EQ(RTNAME(FPow16k)(Real<16>{0.3}, Int<8>{0}), Real<16>{1});
323 EXPECT_EQ(RTNAME(FPow16k)(Real<16>{2}, Int<8>{-1}), Real<16>{0.5});
324 EXPECT_EQ(RTNAME(FPow16k)(Real<16>{0.5}, Int<8>{-1}), Real<16>{2});
325 EXPECT_EQ(RTNAME(FPow16k)(Real<16>{-3}, Int<8>{3}), Real<16>{-27});
326 EXPECT_EQ(RTNAME(FPow16k)(Real<16>{-2}, Int<8>{-3}), Real<16>{-0.125});
327#endif
328
329 // Test some extreme values.
330 if (sizeof(double) == sizeof(std::uint64_t)) {
331 // (0x3FF0000000000001 ** -2147483648) ~ 0x3FEFFFFF00000401
332 double base;
333 *reinterpret_cast<std::uint64_t *>(&base) = 4607182418800017409ULL;
334 double result;
335 *reinterpret_cast<std::uint64_t *>(&result) = 4607182414505051137ULL;
336 EXPECT_TRUE(std::abs(RTNAME(FPow8i)(Real<8>{base},
337 Int<4>{std::numeric_limits<Int<4>>::min()}) -
338 Real<8>{result}) < 0.00000000001);
339
340 // (0x3FF0000000000001 ** 4294967296ULL) ~ 0x3FF00001000007FF
341 *reinterpret_cast<std::uint64_t *>(&base) = 4607182418800017409ULL;
342 *reinterpret_cast<std::uint64_t *>(&result) = 4607182423094986751ULL;
343 EXPECT_TRUE(std::abs(RTNAME(FPow8k)(Real<8>{base}, Int<8>{4294967296ULL}) -
344 Real<8>{result}) < 0.00000000001);
345 }
346}