1//===-- runtime/numeric.cpp -----------------------------------------------===//
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 "flang/Runtime/numeric.h"
10#include "terminator.h"
11#include "flang/Common/float128.h"
12#include <cfloat>
13#include <climits>
14#include <cmath>
15#include <limits>
16
17namespace Fortran::runtime {
18
19template <typename RES>
20inline RT_API_ATTRS RES getIntArgValue(const char *source, int line, void *arg,
21 int kind, std::int64_t defaultValue, int resKind) {
22 RES res;
23 if (!arg) {
24 res = static_cast<RES>(defaultValue);
25 } else if (kind == 1) {
26 res = static_cast<RES>(
27 *static_cast<CppTypeFor<TypeCategory::Integer, 1> *>(arg));
28 } else if (kind == 2) {
29 res = static_cast<RES>(
30 *static_cast<CppTypeFor<TypeCategory::Integer, 2> *>(arg));
31 } else if (kind == 4) {
32 res = static_cast<RES>(
33 *static_cast<CppTypeFor<TypeCategory::Integer, 4> *>(arg));
34 } else if (kind == 8) {
35 res = static_cast<RES>(
36 *static_cast<CppTypeFor<TypeCategory::Integer, 8> *>(arg));
37#ifdef __SIZEOF_INT128__
38 } else if (kind == 16) {
39 if (resKind != 16) {
40 Terminator{source, line}.Crash("Unexpected integer kind in runtime");
41 }
42 res = static_cast<RES>(
43 *static_cast<CppTypeFor<TypeCategory::Integer, 16> *>(arg));
44#endif
45 } else {
46 Terminator{source, line}.Crash("Unexpected integer kind in runtime");
47 }
48 return res;
49}
50
51// NINT (16.9.141)
52template <typename RESULT, typename ARG>
53inline RT_API_ATTRS RESULT Nint(ARG x) {
54 if (x >= 0) {
55 return std::trunc(x + ARG{0.5});
56 } else {
57 return std::trunc(x - ARG{0.5});
58 }
59}
60
61// CEILING & FLOOR (16.9.43, .79)
62template <typename RESULT, typename ARG>
63inline RT_API_ATTRS RESULT Ceiling(ARG x) {
64 return std::ceil(x);
65}
66template <typename RESULT, typename ARG>
67inline RT_API_ATTRS RESULT Floor(ARG x) {
68 return std::floor(x);
69}
70
71// EXPONENT (16.9.75)
72template <typename RESULT, typename ARG>
73inline RT_API_ATTRS RESULT Exponent(ARG x) {
74 if (std::isinf(x) || std::isnan(x)) {
75 return std::numeric_limits<RESULT>::max(); // +/-Inf, NaN -> HUGE(0)
76 } else if (x == 0) {
77 return 0; // 0 -> 0
78 } else {
79 return std::ilogb(x) + 1;
80 }
81}
82
83// Suppress the warnings about calling __host__-only std::frexp,
84// defined in C++ STD header files, from __device__ code.
85RT_DIAG_PUSH
86RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN
87
88// FRACTION (16.9.80)
89template <typename T> inline RT_API_ATTRS T Fraction(T x) {
90 if (std::isnan(x)) {
91 return x; // NaN -> same NaN
92 } else if (std::isinf(x)) {
93 return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
94 } else if (x == 0) {
95 return x; // 0 -> same 0
96 } else {
97 int ignoredExp;
98 return std::frexp(x, &ignoredExp);
99 }
100}
101
102RT_DIAG_POP
103
104// SET_EXPONENT (16.9.171)
105template <typename T> inline RT_API_ATTRS T SetExponent(T x, std::int64_t p) {
106 if (std::isnan(x)) {
107 return x; // NaN -> same NaN
108 } else if (std::isinf(x)) {
109 return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
110 } else if (x == 0) {
111 return x; // return negative zero if x is negative zero
112 } else {
113 int expo{std::ilogb(x) + 1};
114 auto ip{static_cast<int>(p - expo)};
115 if (ip != p - expo) {
116 ip = p < 0 ? std::numeric_limits<int>::min()
117 : std::numeric_limits<int>::max();
118 }
119 return std::ldexp(x, ip); // x*2**(p-e)
120 }
121}
122
123// MOD & MODULO (16.9.135, .136)
124template <bool IS_MODULO, typename T>
125inline RT_API_ATTRS T IntMod(T x, T p, const char *sourceFile, int sourceLine) {
126 if (p == 0) {
127 Terminator{sourceFile, sourceLine}.Crash(
128 IS_MODULO ? "MODULO with P==0" : "MOD with P==0");
129 }
130 auto mod{x - (x / p) * p};
131 if (IS_MODULO && (x > 0) != (p > 0)) {
132 mod += p;
133 }
134 return mod;
135}
136template <bool IS_MODULO, typename T>
137inline RT_API_ATTRS T RealMod(
138 T a, T p, const char *sourceFile, int sourceLine) {
139 if (p == 0) {
140 Terminator{sourceFile, sourceLine}.Crash(
141 IS_MODULO ? "MODULO with P==0" : "MOD with P==0");
142 }
143 if (std::isnan(a) || std::isnan(p) || std::isinf(a)) {
144 return std::numeric_limits<T>::quiet_NaN();
145 } else if (std::isinf(p)) {
146 return a;
147 }
148 T aAbs{std::abs(a)};
149 T pAbs{std::abs(p)};
150 if (aAbs <= static_cast<T>(std::numeric_limits<std::int64_t>::max()) &&
151 pAbs <= static_cast<T>(std::numeric_limits<std::int64_t>::max())) {
152 if (auto aInt{static_cast<std::int64_t>(a)}; a == aInt) {
153 if (auto pInt{static_cast<std::int64_t>(p)}; p == pInt) {
154 // Fast exact case for integer operands
155 auto mod{aInt - (aInt / pInt) * pInt};
156 if (IS_MODULO && (aInt > 0) != (pInt > 0)) {
157 mod += pInt;
158 }
159 return static_cast<T>(mod);
160 }
161 }
162 }
163 if constexpr (std::is_same_v<T, float> || std::is_same_v<T, double> ||
164 std::is_same_v<T, long double>) {
165 // std::fmod() semantics on signed operands seems to match
166 // the requirements of MOD(). MODULO() needs adjustment.
167 T result{std::fmod(a, p)};
168 if constexpr (IS_MODULO) {
169 if ((a < 0) != (p < 0)) {
170 if (result == 0.) {
171 result = -result;
172 } else {
173 result += p;
174 }
175 }
176 }
177 return result;
178 } else {
179 // The standard defines MOD(a,p)=a-AINT(a/p)*p and
180 // MODULO(a,p)=a-FLOOR(a/p)*p, but those definitions lose
181 // precision badly due to cancellation when ABS(a) is
182 // much larger than ABS(p).
183 // Insights:
184 // - MOD(a,p)=MOD(a-n*p,p) when a>0, p>0, integer n>0, and a>=n*p
185 // - when n is a power of two, n*p is exact
186 // - as a>=n*p, a-n*p does not round.
187 // So repeatedly reduce a by all n*p in decreasing order of n;
188 // what's left is the desired remainder. This is basically
189 // the same algorithm as arbitrary precision binary long division,
190 // discarding the quotient.
191 T tmp{aAbs};
192 for (T adj{SetExponent(pAbs, Exponent<int>(aAbs))}; tmp >= pAbs; adj /= 2) {
193 if (tmp >= adj) {
194 tmp -= adj;
195 if (tmp == 0) {
196 break;
197 }
198 }
199 }
200 if (a < 0) {
201 tmp = -tmp;
202 }
203 if constexpr (IS_MODULO) {
204 if ((a < 0) != (p < 0)) {
205 tmp += p;
206 }
207 }
208 return tmp;
209 }
210}
211
212// RRSPACING (16.9.164)
213template <int PREC, typename T> inline RT_API_ATTRS T RRSpacing(T x) {
214 if (std::isnan(x)) {
215 return x; // NaN -> same NaN
216 } else if (std::isinf(x)) {
217 return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
218 } else if (x == 0) {
219 return 0; // 0 -> 0
220 } else {
221 return std::ldexp(std::abs(x), PREC - (std::ilogb(x) + 1));
222 }
223}
224
225// SCALE (16.9.166)
226template <typename T> inline RT_API_ATTRS T Scale(T x, std::int64_t p) {
227 auto ip{static_cast<int>(p)};
228 if (ip != p) {
229 ip = p < 0 ? std::numeric_limits<int>::min()
230 : std::numeric_limits<int>::max();
231 }
232 return std::ldexp(x, p); // x*2**p
233}
234
235// SELECTED_INT_KIND (16.9.169)
236template <typename T>
237inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedIntKind(T x) {
238 if (x <= 2) {
239 return 1;
240 } else if (x <= 4) {
241 return 2;
242 } else if (x <= 9) {
243 return 4;
244 } else if (x <= 18) {
245 return 8;
246#ifdef __SIZEOF_INT128__
247 } else if (x <= 38) {
248 return 16;
249#endif
250 }
251 return -1;
252}
253
254// SELECTED_REAL_KIND (16.9.170)
255template <typename P, typename R, typename D>
256inline RT_API_ATTRS CppTypeFor<TypeCategory::Integer, 4> SelectedRealKind(
257 P p, R r, D d) {
258 if (d != 2) {
259 return -5;
260 }
261
262 int error{0};
263 int kind{0};
264 if (p <= 3) {
265 kind = 2;
266 } else if (p <= 6) {
267 kind = 4;
268 } else if (p <= 15) {
269 kind = 8;
270#if LDBL_MANT_DIG == 64
271 } else if (p <= 18) {
272 kind = 10;
273 } else if (p <= 33) {
274 kind = 16;
275#elif LDBL_MANT_DIG == 113
276 } else if (p <= 33) {
277 kind = 16;
278#endif
279 } else {
280 error -= 1;
281 }
282
283 if (r <= 4) {
284 kind = kind < 2 ? 2 : kind;
285 } else if (r <= 37) {
286 kind = kind < 3 ? (p == 3 ? 4 : 3) : kind;
287 } else if (r <= 307) {
288 kind = kind < 8 ? 8 : kind;
289#if LDBL_MANT_DIG == 64
290 } else if (r <= 4931) {
291 kind = kind < 10 ? 10 : kind;
292#elif LDBL_MANT_DIG == 113
293 } else if (r <= 4931) {
294 kind = kind < 16 ? 16 : kind;
295#endif
296 } else {
297 error -= 2;
298 }
299
300 return error ? error : kind;
301}
302
303// SPACING (16.9.180)
304template <int PREC, typename T> inline RT_API_ATTRS T Spacing(T x) {
305 if (std::isnan(x)) {
306 return x; // NaN -> same NaN
307 } else if (std::isinf(x)) {
308 return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
309 } else if (x == 0) {
310 // The standard-mandated behavior seems broken, since TINY() can't be
311 // subnormal.
312 return std::numeric_limits<T>::min(); // 0 -> TINY(x)
313 } else {
314 T result{
315 std::ldexp(static_cast<T>(1.0), std::ilogb(x) + 1 - PREC)}; // 2**(e-p)
316 return result == 0 ? /*TINY(x)*/ std::numeric_limits<T>::min() : result;
317 }
318}
319
320// NEAREST (16.9.139)
321template <int PREC, typename T>
322inline RT_API_ATTRS T Nearest(T x, bool positive) {
323 if (positive) {
324 return std::nextafter(x, std::numeric_limits<T>::infinity());
325 } else {
326 return std::nextafter(x, -std::numeric_limits<T>::infinity());
327 }
328}
329
330// Exponentiation operator for (Real ** Integer) cases (10.1.5.2.1).
331template <typename BTy, typename ETy>
332RT_API_ATTRS BTy FPowI(BTy base, ETy exp) {
333 if (exp == ETy{0})
334 return BTy{1};
335 bool isNegativePower{exp < ETy{0}};
336 bool isMinPower{exp == std::numeric_limits<ETy>::min()};
337 if (isMinPower) {
338 exp = std::numeric_limits<ETy>::max();
339 } else if (isNegativePower) {
340 exp = -exp;
341 }
342 BTy result{1};
343 BTy origBase{base};
344 while (true) {
345 if (exp & ETy{1}) {
346 result *= base;
347 }
348 exp >>= 1;
349 if (exp == ETy{0}) {
350 break;
351 }
352 base *= base;
353 }
354 if (isMinPower) {
355 result *= origBase;
356 }
357 if (isNegativePower) {
358 result = BTy{1} / result;
359 }
360 return result;
361}
362
363extern "C" {
364RT_EXT_API_GROUP_BEGIN
365
366CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling4_1)(
367 CppTypeFor<TypeCategory::Real, 4> x) {
368 return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
369}
370CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling4_2)(
371 CppTypeFor<TypeCategory::Real, 4> x) {
372 return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
373}
374CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling4_4)(
375 CppTypeFor<TypeCategory::Real, 4> x) {
376 return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
377}
378CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling4_8)(
379 CppTypeFor<TypeCategory::Real, 4> x) {
380 return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
381}
382#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
383CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling4_16)(
384 CppTypeFor<TypeCategory::Real, 4> x) {
385 return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
386}
387#endif
388CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling8_1)(
389 CppTypeFor<TypeCategory::Real, 8> x) {
390 return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
391}
392CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling8_2)(
393 CppTypeFor<TypeCategory::Real, 8> x) {
394 return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
395}
396CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling8_4)(
397 CppTypeFor<TypeCategory::Real, 8> x) {
398 return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
399}
400CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling8_8)(
401 CppTypeFor<TypeCategory::Real, 8> x) {
402 return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
403}
404#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
405CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling8_16)(
406 CppTypeFor<TypeCategory::Real, 8> x) {
407 return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
408}
409#endif
410#if LDBL_MANT_DIG == 64
411CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling10_1)(
412 CppTypeFor<TypeCategory::Real, 10> x) {
413 return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
414}
415CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling10_2)(
416 CppTypeFor<TypeCategory::Real, 10> x) {
417 return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
418}
419CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling10_4)(
420 CppTypeFor<TypeCategory::Real, 10> x) {
421 return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
422}
423CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling10_8)(
424 CppTypeFor<TypeCategory::Real, 10> x) {
425 return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
426}
427#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
428CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling10_16)(
429 CppTypeFor<TypeCategory::Real, 10> x) {
430 return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
431}
432#endif
433#elif LDBL_MANT_DIG == 113
434CppTypeFor<TypeCategory::Integer, 1> RTDEF(Ceiling16_1)(
435 CppTypeFor<TypeCategory::Real, 16> x) {
436 return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
437}
438CppTypeFor<TypeCategory::Integer, 2> RTDEF(Ceiling16_2)(
439 CppTypeFor<TypeCategory::Real, 16> x) {
440 return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
441}
442CppTypeFor<TypeCategory::Integer, 4> RTDEF(Ceiling16_4)(
443 CppTypeFor<TypeCategory::Real, 16> x) {
444 return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
445}
446CppTypeFor<TypeCategory::Integer, 8> RTDEF(Ceiling16_8)(
447 CppTypeFor<TypeCategory::Real, 16> x) {
448 return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
449}
450#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
451CppTypeFor<TypeCategory::Integer, 16> RTDEF(Ceiling16_16)(
452 CppTypeFor<TypeCategory::Real, 16> x) {
453 return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
454}
455#endif
456#endif
457
458CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent4_4)(
459 CppTypeFor<TypeCategory::Real, 4> x) {
460 return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
461}
462CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent4_8)(
463 CppTypeFor<TypeCategory::Real, 4> x) {
464 return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
465}
466CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent8_4)(
467 CppTypeFor<TypeCategory::Real, 8> x) {
468 return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
469}
470CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent8_8)(
471 CppTypeFor<TypeCategory::Real, 8> x) {
472 return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
473}
474#if LDBL_MANT_DIG == 64
475CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent10_4)(
476 CppTypeFor<TypeCategory::Real, 10> x) {
477 return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
478}
479CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent10_8)(
480 CppTypeFor<TypeCategory::Real, 10> x) {
481 return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
482}
483#elif LDBL_MANT_DIG == 113
484CppTypeFor<TypeCategory::Integer, 4> RTDEF(Exponent16_4)(
485 CppTypeFor<TypeCategory::Real, 16> x) {
486 return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
487}
488CppTypeFor<TypeCategory::Integer, 8> RTDEF(Exponent16_8)(
489 CppTypeFor<TypeCategory::Real, 16> x) {
490 return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
491}
492#endif
493
494CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor4_1)(
495 CppTypeFor<TypeCategory::Real, 4> x) {
496 return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
497}
498CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor4_2)(
499 CppTypeFor<TypeCategory::Real, 4> x) {
500 return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
501}
502CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor4_4)(
503 CppTypeFor<TypeCategory::Real, 4> x) {
504 return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
505}
506CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor4_8)(
507 CppTypeFor<TypeCategory::Real, 4> x) {
508 return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
509}
510#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
511CppTypeFor<TypeCategory::Integer, 16> RTDEF(Floor4_16)(
512 CppTypeFor<TypeCategory::Real, 4> x) {
513 return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
514}
515#endif
516CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor8_1)(
517 CppTypeFor<TypeCategory::Real, 8> x) {
518 return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
519}
520CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor8_2)(
521 CppTypeFor<TypeCategory::Real, 8> x) {
522 return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
523}
524CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor8_4)(
525 CppTypeFor<TypeCategory::Real, 8> x) {
526 return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
527}
528CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor8_8)(
529 CppTypeFor<TypeCategory::Real, 8> x) {
530 return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
531}
532#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
533CppTypeFor<TypeCategory::Integer, 16> RTDEF(Floor8_16)(
534 CppTypeFor<TypeCategory::Real, 8> x) {
535 return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
536}
537#endif
538#if LDBL_MANT_DIG == 64
539CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor10_1)(
540 CppTypeFor<TypeCategory::Real, 10> x) {
541 return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
542}
543CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor10_2)(
544 CppTypeFor<TypeCategory::Real, 10> x) {
545 return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
546}
547CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor10_4)(
548 CppTypeFor<TypeCategory::Real, 10> x) {
549 return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
550}
551CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor10_8)(
552 CppTypeFor<TypeCategory::Real, 10> x) {
553 return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
554}
555#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
556CppTypeFor<TypeCategory::Integer, 16> RTDEF(Floor10_16)(
557 CppTypeFor<TypeCategory::Real, 10> x) {
558 return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
559}
560#endif
561#elif LDBL_MANT_DIG == 113
562CppTypeFor<TypeCategory::Integer, 1> RTDEF(Floor16_1)(
563 CppTypeFor<TypeCategory::Real, 16> x) {
564 return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
565}
566CppTypeFor<TypeCategory::Integer, 2> RTDEF(Floor16_2)(
567 CppTypeFor<TypeCategory::Real, 16> x) {
568 return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
569}
570CppTypeFor<TypeCategory::Integer, 4> RTDEF(Floor16_4)(
571 CppTypeFor<TypeCategory::Real, 16> x) {
572 return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
573}
574CppTypeFor<TypeCategory::Integer, 8> RTDEF(Floor16_8)(
575 CppTypeFor<TypeCategory::Real, 16> x) {
576 return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
577}
578#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
579CppTypeFor<TypeCategory::Integer, 16> RTDEF(Floor16_16)(
580 CppTypeFor<TypeCategory::Real, 16> x) {
581 return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
582}
583#endif
584#endif
585
586CppTypeFor<TypeCategory::Real, 4> RTDEF(Fraction4)(
587 CppTypeFor<TypeCategory::Real, 4> x) {
588 return Fraction(x);
589}
590CppTypeFor<TypeCategory::Real, 8> RTDEF(Fraction8)(
591 CppTypeFor<TypeCategory::Real, 8> x) {
592 return Fraction(x);
593}
594#if LDBL_MANT_DIG == 64
595CppTypeFor<TypeCategory::Real, 10> RTDEF(Fraction10)(
596 CppTypeFor<TypeCategory::Real, 10> x) {
597 return Fraction(x);
598}
599#elif LDBL_MANT_DIG == 113
600CppTypeFor<TypeCategory::Real, 16> RTDEF(Fraction16)(
601 CppTypeFor<TypeCategory::Real, 16> x) {
602 return Fraction(x);
603}
604#endif
605
606bool RTDEF(IsFinite4)(CppTypeFor<TypeCategory::Real, 4> x) {
607 return std::isfinite(x);
608}
609bool RTDEF(IsFinite8)(CppTypeFor<TypeCategory::Real, 8> x) {
610 return std::isfinite(x);
611}
612#if LDBL_MANT_DIG == 64
613bool RTDEF(IsFinite10)(CppTypeFor<TypeCategory::Real, 10> x) {
614 return std::isfinite(x);
615}
616#elif LDBL_MANT_DIG == 113
617bool RTDEF(IsFinite16)(CppTypeFor<TypeCategory::Real, 16> x) {
618 return std::isfinite(x);
619}
620#endif
621
622bool RTDEF(IsNaN4)(CppTypeFor<TypeCategory::Real, 4> x) {
623 return std::isnan(x);
624}
625bool RTDEF(IsNaN8)(CppTypeFor<TypeCategory::Real, 8> x) {
626 return std::isnan(x);
627}
628#if LDBL_MANT_DIG == 64
629bool RTDEF(IsNaN10)(CppTypeFor<TypeCategory::Real, 10> x) {
630 return std::isnan(x);
631}
632#elif LDBL_MANT_DIG == 113
633bool RTDEF(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
634 return std::isnan(x);
635}
636#endif
637
638CppTypeFor<TypeCategory::Integer, 1> RTDEF(ModInteger1)(
639 CppTypeFor<TypeCategory::Integer, 1> x,
640 CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
641 int sourceLine) {
642 return IntMod<false>(x, p, sourceFile, sourceLine);
643}
644CppTypeFor<TypeCategory::Integer, 2> RTDEF(ModInteger2)(
645 CppTypeFor<TypeCategory::Integer, 2> x,
646 CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
647 int sourceLine) {
648 return IntMod<false>(x, p, sourceFile, sourceLine);
649}
650CppTypeFor<TypeCategory::Integer, 4> RTDEF(ModInteger4)(
651 CppTypeFor<TypeCategory::Integer, 4> x,
652 CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
653 int sourceLine) {
654 return IntMod<false>(x, p, sourceFile, sourceLine);
655}
656CppTypeFor<TypeCategory::Integer, 8> RTDEF(ModInteger8)(
657 CppTypeFor<TypeCategory::Integer, 8> x,
658 CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
659 int sourceLine) {
660 return IntMod<false>(x, p, sourceFile, sourceLine);
661}
662#ifdef __SIZEOF_INT128__
663CppTypeFor<TypeCategory::Integer, 16> RTDEF(ModInteger16)(
664 CppTypeFor<TypeCategory::Integer, 16> x,
665 CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
666 int sourceLine) {
667 return IntMod<false>(x, p, sourceFile, sourceLine);
668}
669#endif
670CppTypeFor<TypeCategory::Real, 4> RTDEF(ModReal4)(
671 CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
672 const char *sourceFile, int sourceLine) {
673 return RealMod<false>(x, p, sourceFile, sourceLine);
674}
675CppTypeFor<TypeCategory::Real, 8> RTDEF(ModReal8)(
676 CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
677 const char *sourceFile, int sourceLine) {
678 return RealMod<false>(x, p, sourceFile, sourceLine);
679}
680#if LDBL_MANT_DIG == 64
681CppTypeFor<TypeCategory::Real, 10> RTDEF(ModReal10)(
682 CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
683 const char *sourceFile, int sourceLine) {
684 return RealMod<false>(x, p, sourceFile, sourceLine);
685}
686#elif LDBL_MANT_DIG == 113
687CppTypeFor<TypeCategory::Real, 16> RTDEF(ModReal16)(
688 CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
689 const char *sourceFile, int sourceLine) {
690 return RealMod<false>(x, p, sourceFile, sourceLine);
691}
692#endif
693
694CppTypeFor<TypeCategory::Integer, 1> RTDEF(ModuloInteger1)(
695 CppTypeFor<TypeCategory::Integer, 1> x,
696 CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile,
697 int sourceLine) {
698 return IntMod<true>(x, p, sourceFile, sourceLine);
699}
700CppTypeFor<TypeCategory::Integer, 2> RTDEF(ModuloInteger2)(
701 CppTypeFor<TypeCategory::Integer, 2> x,
702 CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile,
703 int sourceLine) {
704 return IntMod<true>(x, p, sourceFile, sourceLine);
705}
706CppTypeFor<TypeCategory::Integer, 4> RTDEF(ModuloInteger4)(
707 CppTypeFor<TypeCategory::Integer, 4> x,
708 CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile,
709 int sourceLine) {
710 return IntMod<true>(x, p, sourceFile, sourceLine);
711}
712CppTypeFor<TypeCategory::Integer, 8> RTDEF(ModuloInteger8)(
713 CppTypeFor<TypeCategory::Integer, 8> x,
714 CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile,
715 int sourceLine) {
716 return IntMod<true>(x, p, sourceFile, sourceLine);
717}
718#ifdef __SIZEOF_INT128__
719CppTypeFor<TypeCategory::Integer, 16> RTDEF(ModuloInteger16)(
720 CppTypeFor<TypeCategory::Integer, 16> x,
721 CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile,
722 int sourceLine) {
723 return IntMod<true>(x, p, sourceFile, sourceLine);
724}
725#endif
726CppTypeFor<TypeCategory::Real, 4> RTDEF(ModuloReal4)(
727 CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p,
728 const char *sourceFile, int sourceLine) {
729 return RealMod<true>(x, p, sourceFile, sourceLine);
730}
731CppTypeFor<TypeCategory::Real, 8> RTDEF(ModuloReal8)(
732 CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p,
733 const char *sourceFile, int sourceLine) {
734 return RealMod<true>(x, p, sourceFile, sourceLine);
735}
736#if LDBL_MANT_DIG == 64
737CppTypeFor<TypeCategory::Real, 10> RTDEF(ModuloReal10)(
738 CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p,
739 const char *sourceFile, int sourceLine) {
740 return RealMod<true>(x, p, sourceFile, sourceLine);
741}
742#elif LDBL_MANT_DIG == 113
743CppTypeFor<TypeCategory::Real, 16> RTDEF(ModuloReal16)(
744 CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p,
745 const char *sourceFile, int sourceLine) {
746 return RealMod<true>(x, p, sourceFile, sourceLine);
747}
748#endif
749
750CppTypeFor<TypeCategory::Real, 4> RTDEF(Nearest4)(
751 CppTypeFor<TypeCategory::Real, 4> x, bool positive) {
752 return Nearest<24>(x, positive);
753}
754CppTypeFor<TypeCategory::Real, 8> RTDEF(Nearest8)(
755 CppTypeFor<TypeCategory::Real, 8> x, bool positive) {
756 return Nearest<53>(x, positive);
757}
758#if LDBL_MANT_DIG == 64
759CppTypeFor<TypeCategory::Real, 10> RTDEF(Nearest10)(
760 CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
761 return Nearest<64>(x, positive);
762}
763#elif LDBL_MANT_DIG == 113
764CppTypeFor<TypeCategory::Real, 16> RTDEF(Nearest16)(
765 CppTypeFor<TypeCategory::Real, 16> x, bool positive) {
766 return Nearest<113>(x, positive);
767}
768#endif
769
770CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint4_1)(
771 CppTypeFor<TypeCategory::Real, 4> x) {
772 return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
773}
774CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint4_2)(
775 CppTypeFor<TypeCategory::Real, 4> x) {
776 return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
777}
778CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint4_4)(
779 CppTypeFor<TypeCategory::Real, 4> x) {
780 return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
781}
782CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint4_8)(
783 CppTypeFor<TypeCategory::Real, 4> x) {
784 return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
785}
786#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
787CppTypeFor<TypeCategory::Integer, 16> RTDEF(Nint4_16)(
788 CppTypeFor<TypeCategory::Real, 4> x) {
789 return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
790}
791#endif
792CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint8_1)(
793 CppTypeFor<TypeCategory::Real, 8> x) {
794 return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
795}
796CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint8_2)(
797 CppTypeFor<TypeCategory::Real, 8> x) {
798 return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
799}
800CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint8_4)(
801 CppTypeFor<TypeCategory::Real, 8> x) {
802 return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
803}
804CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint8_8)(
805 CppTypeFor<TypeCategory::Real, 8> x) {
806 return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
807}
808#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
809CppTypeFor<TypeCategory::Integer, 16> RTDEF(Nint8_16)(
810 CppTypeFor<TypeCategory::Real, 8> x) {
811 return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
812}
813#endif
814#if LDBL_MANT_DIG == 64
815CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint10_1)(
816 CppTypeFor<TypeCategory::Real, 10> x) {
817 return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
818}
819CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint10_2)(
820 CppTypeFor<TypeCategory::Real, 10> x) {
821 return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
822}
823CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint10_4)(
824 CppTypeFor<TypeCategory::Real, 10> x) {
825 return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
826}
827CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint10_8)(
828 CppTypeFor<TypeCategory::Real, 10> x) {
829 return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
830}
831#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
832CppTypeFor<TypeCategory::Integer, 16> RTDEF(Nint10_16)(
833 CppTypeFor<TypeCategory::Real, 10> x) {
834 return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
835}
836#endif
837#elif LDBL_MANT_DIG == 113
838CppTypeFor<TypeCategory::Integer, 1> RTDEF(Nint16_1)(
839 CppTypeFor<TypeCategory::Real, 16> x) {
840 return Nint<CppTypeFor<TypeCategory::Integer, 1>>(x);
841}
842CppTypeFor<TypeCategory::Integer, 2> RTDEF(Nint16_2)(
843 CppTypeFor<TypeCategory::Real, 16> x) {
844 return Nint<CppTypeFor<TypeCategory::Integer, 2>>(x);
845}
846CppTypeFor<TypeCategory::Integer, 4> RTDEF(Nint16_4)(
847 CppTypeFor<TypeCategory::Real, 16> x) {
848 return Nint<CppTypeFor<TypeCategory::Integer, 4>>(x);
849}
850CppTypeFor<TypeCategory::Integer, 8> RTDEF(Nint16_8)(
851 CppTypeFor<TypeCategory::Real, 16> x) {
852 return Nint<CppTypeFor<TypeCategory::Integer, 8>>(x);
853}
854#if defined __SIZEOF_INT128__ && !AVOID_NATIVE_UINT128_T
855CppTypeFor<TypeCategory::Integer, 16> RTDEF(Nint16_16)(
856 CppTypeFor<TypeCategory::Real, 16> x) {
857 return Nint<CppTypeFor<TypeCategory::Integer, 16>>(x);
858}
859#endif
860#endif
861
862CppTypeFor<TypeCategory::Real, 4> RTDEF(RRSpacing4)(
863 CppTypeFor<TypeCategory::Real, 4> x) {
864 return RRSpacing<24>(x);
865}
866CppTypeFor<TypeCategory::Real, 8> RTDEF(RRSpacing8)(
867 CppTypeFor<TypeCategory::Real, 8> x) {
868 return RRSpacing<53>(x);
869}
870#if LDBL_MANT_DIG == 64
871CppTypeFor<TypeCategory::Real, 10> RTDEF(RRSpacing10)(
872 CppTypeFor<TypeCategory::Real, 10> x) {
873 return RRSpacing<64>(x);
874}
875#elif LDBL_MANT_DIG == 113
876CppTypeFor<TypeCategory::Real, 16> RTDEF(RRSpacing16)(
877 CppTypeFor<TypeCategory::Real, 16> x) {
878 return RRSpacing<113>(x);
879}
880#endif
881
882CppTypeFor<TypeCategory::Real, 4> RTDEF(SetExponent4)(
883 CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
884 return SetExponent(x, p);
885}
886CppTypeFor<TypeCategory::Real, 8> RTDEF(SetExponent8)(
887 CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
888 return SetExponent(x, p);
889}
890#if LDBL_MANT_DIG == 64
891CppTypeFor<TypeCategory::Real, 10> RTDEF(SetExponent10)(
892 CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
893 return SetExponent(x, p);
894}
895#elif LDBL_MANT_DIG == 113
896CppTypeFor<TypeCategory::Real, 16> RTDEF(SetExponent16)(
897 CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
898 return SetExponent(x, p);
899}
900#endif
901
902CppTypeFor<TypeCategory::Real, 4> RTDEF(Scale4)(
903 CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
904 return Scale(x, p);
905}
906CppTypeFor<TypeCategory::Real, 8> RTDEF(Scale8)(
907 CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
908 return Scale(x, p);
909}
910#if LDBL_MANT_DIG == 64
911CppTypeFor<TypeCategory::Real, 10> RTDEF(Scale10)(
912 CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
913 return Scale(x, p);
914}
915#elif LDBL_MANT_DIG == 113
916CppTypeFor<TypeCategory::Real, 16> RTDEF(Scale16)(
917 CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
918 return Scale(x, p);
919}
920#endif
921
922// SELECTED_INT_KIND
923CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedIntKind)(
924 const char *source, int line, void *x, int xKind) {
925#ifdef __SIZEOF_INT128__
926 CppTypeFor<TypeCategory::Integer, 16> r =
927 getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
928 source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 16);
929#else
930 std::int64_t r = getIntArgValue<std::int64_t>(
931 source, line, x, xKind, /*defaultValue*/ 0, /*resKind*/ 8);
932#endif
933 return SelectedIntKind(r);
934}
935
936// SELECTED_REAL_KIND
937CppTypeFor<TypeCategory::Integer, 4> RTDEF(SelectedRealKind)(const char *source,
938 int line, void *precision, int pKind, void *range, int rKind, void *radix,
939 int dKind) {
940#ifdef __SIZEOF_INT128__
941 CppTypeFor<TypeCategory::Integer, 16> p =
942 getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
943 source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 16);
944 CppTypeFor<TypeCategory::Integer, 16> r =
945 getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
946 source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 16);
947 CppTypeFor<TypeCategory::Integer, 16> d =
948 getIntArgValue<CppTypeFor<TypeCategory::Integer, 16>>(
949 source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 16);
950#else
951 std::int64_t p = getIntArgValue<std::int64_t>(
952 source, line, precision, pKind, /*defaultValue*/ 0, /*resKind*/ 8);
953 std::int64_t r = getIntArgValue<std::int64_t>(
954 source, line, range, rKind, /*defaultValue*/ 0, /*resKind*/ 8);
955 std::int64_t d = getIntArgValue<std::int64_t>(
956 source, line, radix, dKind, /*defaultValue*/ 2, /*resKind*/ 8);
957#endif
958 return SelectedRealKind(p, r, d);
959}
960
961CppTypeFor<TypeCategory::Real, 4> RTDEF(Spacing4)(
962 CppTypeFor<TypeCategory::Real, 4> x) {
963 return Spacing<24>(x);
964}
965CppTypeFor<TypeCategory::Real, 8> RTDEF(Spacing8)(
966 CppTypeFor<TypeCategory::Real, 8> x) {
967 return Spacing<53>(x);
968}
969#if LDBL_MANT_DIG == 64
970CppTypeFor<TypeCategory::Real, 10> RTDEF(Spacing10)(
971 CppTypeFor<TypeCategory::Real, 10> x) {
972 return Spacing<64>(x);
973}
974#elif LDBL_MANT_DIG == 113
975CppTypeFor<TypeCategory::Real, 16> RTDEF(Spacing16)(
976 CppTypeFor<TypeCategory::Real, 16> x) {
977 return Spacing<113>(x);
978}
979#endif
980
981CppTypeFor<TypeCategory::Real, 4> RTDEF(FPow4i)(
982 CppTypeFor<TypeCategory::Real, 4> b,
983 CppTypeFor<TypeCategory::Integer, 4> e) {
984 return FPowI(b, e);
985}
986CppTypeFor<TypeCategory::Real, 8> RTDEF(FPow8i)(
987 CppTypeFor<TypeCategory::Real, 8> b,
988 CppTypeFor<TypeCategory::Integer, 4> e) {
989 return FPowI(b, e);
990}
991#if LDBL_MANT_DIG == 64
992CppTypeFor<TypeCategory::Real, 10> RTDEF(FPow10i)(
993 CppTypeFor<TypeCategory::Real, 10> b,
994 CppTypeFor<TypeCategory::Integer, 4> e) {
995 return FPowI(b, e);
996}
997#endif
998#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
999CppTypeFor<TypeCategory::Real, 16> RTDEF(FPow16i)(
1000 CppTypeFor<TypeCategory::Real, 16> b,
1001 CppTypeFor<TypeCategory::Integer, 4> e) {
1002 return FPowI(b, e);
1003}
1004#endif
1005
1006CppTypeFor<TypeCategory::Real, 4> RTDEF(FPow4k)(
1007 CppTypeFor<TypeCategory::Real, 4> b,
1008 CppTypeFor<TypeCategory::Integer, 8> e) {
1009 return FPowI(b, e);
1010}
1011CppTypeFor<TypeCategory::Real, 8> RTDEF(FPow8k)(
1012 CppTypeFor<TypeCategory::Real, 8> b,
1013 CppTypeFor<TypeCategory::Integer, 8> e) {
1014 return FPowI(b, e);
1015}
1016#if LDBL_MANT_DIG == 64
1017CppTypeFor<TypeCategory::Real, 10> RTDEF(FPow10k)(
1018 CppTypeFor<TypeCategory::Real, 10> b,
1019 CppTypeFor<TypeCategory::Integer, 8> e) {
1020 return FPowI(b, e);
1021}
1022#endif
1023#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
1024CppTypeFor<TypeCategory::Real, 16> RTDEF(FPow16k)(
1025 CppTypeFor<TypeCategory::Real, 16> b,
1026 CppTypeFor<TypeCategory::Integer, 8> e) {
1027 return FPowI(b, e);
1028}
1029#endif
1030
1031RT_EXT_API_GROUP_END
1032} // extern "C"
1033} // namespace Fortran::runtime
1034

source code of flang/runtime/numeric.cpp