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 "flang/Common/long-double.h"
11 #include <climits>
12 #include <cmath>
13 #include <limits>
14 
15 namespace Fortran::runtime {
16 
17 // AINT
18 template <typename RESULT, typename ARG> inline RESULT Aint(ARG x) {
19   return std::trunc(x);
20 }
21 
22 // ANINT & NINT
23 template <typename RESULT, typename ARG> inline RESULT Anint(ARG x) {
24   if (x >= 0) {
25     return std::trunc(x + ARG{0.5});
26   } else {
27     return std::trunc(x - ARG{0.5});
28   }
29 }
30 
31 // CEILING & FLOOR (16.9.43, .79)
32 template <typename RESULT, typename ARG> inline RESULT Ceiling(ARG x) {
33   return std::ceil(x);
34 }
35 template <typename RESULT, typename ARG> inline RESULT Floor(ARG x) {
36   return std::floor(x);
37 }
38 
39 // EXPONENT (16.9.75)
40 template <typename RESULT, typename ARG> inline RESULT Exponent(ARG x) {
41   if (std::isinf(x) || std::isnan(x)) {
42     return std::numeric_limits<RESULT>::max(); // +/-Inf, NaN -> HUGE(0)
43   } else if (x == 0) {
44     return 0; // 0 -> 0
45   } else {
46     return std::ilogb(x) + 1;
47   }
48 }
49 
50 // FRACTION (16.9.80)
51 template <typename T> inline T Fraction(T x) {
52   if (std::isnan(x)) {
53     return x; // NaN -> same NaN
54   } else if (std::isinf(x)) {
55     return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
56   } else if (x == 0) {
57     return 0; // 0 -> 0
58   } else {
59     int ignoredExp;
60     return std::frexp(x, &ignoredExp);
61   }
62 }
63 
64 // MOD & MODULO (16.9.135, .136)
65 template <bool IS_MODULO, typename T> inline T IntMod(T x, T p) {
66   auto mod{x - (x / p) * p};
67   if (IS_MODULO && (x > 0) != (p > 0)) {
68     mod += p;
69   }
70   return mod;
71 }
72 template <bool IS_MODULO, typename T> inline T RealMod(T x, T p) {
73   if constexpr (IS_MODULO) {
74     return x - std::floor(x / p) * p;
75   } else {
76     return x - std::trunc(x / p) * p;
77   }
78 }
79 
80 // RRSPACING (16.9.164)
81 template <int PREC, typename T> inline T RRSpacing(T x) {
82   if (std::isnan(x)) {
83     return x; // NaN -> same NaN
84   } else if (std::isinf(x)) {
85     return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
86   } else if (x == 0) {
87     return 0; // 0 -> 0
88   } else {
89     return std::ldexp(std::abs(x), PREC - (std::ilogb(x) + 1));
90   }
91 }
92 
93 // SCALE (16.9.166)
94 template <typename T> inline T Scale(T x, std::int64_t p) {
95   auto ip{static_cast<int>(p)};
96   if (ip != p) {
97     ip = p < 0 ? std::numeric_limits<int>::min()
98                : std::numeric_limits<int>::max();
99   }
100   return std::ldexp(x, p); // x*2**p
101 }
102 
103 // SET_EXPONENT (16.9.171)
104 template <typename T> inline T SetExponent(T x, std::int64_t p) {
105   if (std::isnan(x)) {
106     return x; // NaN -> same NaN
107   } else if (std::isinf(x)) {
108     return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
109   } else if (x == 0) {
110     return 0; // 0 -> 0
111   } else {
112     int expo{std::ilogb(x) + 1};
113     auto ip{static_cast<int>(p - expo)};
114     if (ip != p - expo) {
115       ip = p < 0 ? std::numeric_limits<int>::min()
116                  : std::numeric_limits<int>::max();
117     }
118     return std::ldexp(x, ip); // x*2**(p-e)
119   }
120 }
121 
122 // SPACING (16.9.180)
123 template <int PREC, typename T> inline T Spacing(T x) {
124   if (std::isnan(x)) {
125     return x; // NaN -> same NaN
126   } else if (std::isinf(x)) {
127     return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN
128   } else if (x == 0) {
129     // The standard-mandated behavior seems broken, since TINY() can't be
130     // subnormal.
131     return std::numeric_limits<T>::min(); // 0 -> TINY(x)
132   } else {
133     return std::ldexp(
134         static_cast<T>(1.0), std::ilogb(x) + 1 - PREC); // 2**(e-p)
135   }
136 }
137 
138 // NEAREST (16.9.139)
139 template <int PREC, typename T> inline T Nearest(T x, bool positive) {
140   auto spacing{Spacing<PREC>(x)};
141   if (x == 0) {
142     auto least{std::numeric_limits<T>::denorm_min()};
143     return positive ? least : -least;
144   } else {
145     return positive ? x + spacing : x - spacing;
146   }
147 }
148 
149 extern "C" {
150 
151 CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint4_4)(
152     CppTypeFor<TypeCategory::Real, 4> x) {
153   return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
154 }
155 CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint4_8)(
156     CppTypeFor<TypeCategory::Real, 4> x) {
157   return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
158 }
159 CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint8_4)(
160     CppTypeFor<TypeCategory::Real, 8> x) {
161   return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
162 }
163 CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)(
164     CppTypeFor<TypeCategory::Real, 8> x) {
165   return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
166 }
167 #if LONG_DOUBLE == 80
168 CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)(
169     CppTypeFor<TypeCategory::Real, 4> x) {
170   return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
171 }
172 CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint8_10)(
173     CppTypeFor<TypeCategory::Real, 8> x) {
174   return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
175 }
176 CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint10_4)(
177     CppTypeFor<TypeCategory::Real, 10> x) {
178   return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
179 }
180 CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint10_8)(
181     CppTypeFor<TypeCategory::Real, 10> x) {
182   return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
183 }
184 CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)(
185     CppTypeFor<TypeCategory::Real, 10> x) {
186   return Aint<CppTypeFor<TypeCategory::Real, 10>>(x);
187 }
188 #elif LONG_DOUBLE == 128
189 CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)(
190     CppTypeFor<TypeCategory::Real, 4> x) {
191   return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
192 }
193 CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint8_16)(
194     CppTypeFor<TypeCategory::Real, 8> x) {
195   return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
196 }
197 CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint16_4)(
198     CppTypeFor<TypeCategory::Real, 16> x) {
199   return Aint<CppTypeFor<TypeCategory::Real, 4>>(x);
200 }
201 CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint16_8)(
202     CppTypeFor<TypeCategory::Real, 16> x) {
203   return Aint<CppTypeFor<TypeCategory::Real, 8>>(x);
204 }
205 CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint16_16)(
206     CppTypeFor<TypeCategory::Real, 16> x) {
207   return Aint<CppTypeFor<TypeCategory::Real, 16>>(x);
208 }
209 #endif
210 
211 CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint4_4)(
212     CppTypeFor<TypeCategory::Real, 4> x) {
213   return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
214 }
215 CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint4_8)(
216     CppTypeFor<TypeCategory::Real, 4> x) {
217   return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
218 }
219 CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint8_4)(
220     CppTypeFor<TypeCategory::Real, 8> x) {
221   return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
222 }
223 CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)(
224     CppTypeFor<TypeCategory::Real, 8> x) {
225   return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
226 }
227 #if LONG_DOUBLE == 80
228 CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)(
229     CppTypeFor<TypeCategory::Real, 4> x) {
230   return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
231 }
232 CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint8_10)(
233     CppTypeFor<TypeCategory::Real, 8> x) {
234   return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
235 }
236 CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint10_4)(
237     CppTypeFor<TypeCategory::Real, 10> x) {
238   return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
239 }
240 CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint10_8)(
241     CppTypeFor<TypeCategory::Real, 10> x) {
242   return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
243 }
244 CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)(
245     CppTypeFor<TypeCategory::Real, 10> x) {
246   return Anint<CppTypeFor<TypeCategory::Real, 10>>(x);
247 }
248 #elif LONG_DOUBLE == 128
249 CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)(
250     CppTypeFor<TypeCategory::Real, 4> x) {
251   return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
252 }
253 CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint8_16)(
254     CppTypeFor<TypeCategory::Real, 8> x) {
255   return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
256 }
257 CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint16_4)(
258     CppTypeFor<TypeCategory::Real, 16> x) {
259   return Anint<CppTypeFor<TypeCategory::Real, 4>>(x);
260 }
261 CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint16_8)(
262     CppTypeFor<TypeCategory::Real, 16> x) {
263   return Anint<CppTypeFor<TypeCategory::Real, 8>>(x);
264 }
265 CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint16_16)(
266     CppTypeFor<TypeCategory::Real, 16> x) {
267   return Anint<CppTypeFor<TypeCategory::Real, 16>>(x);
268 }
269 #endif
270 
271 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling4_1)(
272     CppTypeFor<TypeCategory::Real, 4> x) {
273   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
274 }
275 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling4_2)(
276     CppTypeFor<TypeCategory::Real, 4> x) {
277   return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
278 }
279 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling4_4)(
280     CppTypeFor<TypeCategory::Real, 4> x) {
281   return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
282 }
283 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling4_8)(
284     CppTypeFor<TypeCategory::Real, 4> x) {
285   return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
286 }
287 #ifdef __SIZEOF_INT128__
288 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling4_16)(
289     CppTypeFor<TypeCategory::Real, 4> x) {
290   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
291 }
292 #endif
293 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling8_1)(
294     CppTypeFor<TypeCategory::Real, 8> x) {
295   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
296 }
297 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling8_2)(
298     CppTypeFor<TypeCategory::Real, 8> x) {
299   return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
300 }
301 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling8_4)(
302     CppTypeFor<TypeCategory::Real, 8> x) {
303   return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
304 }
305 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling8_8)(
306     CppTypeFor<TypeCategory::Real, 8> x) {
307   return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
308 }
309 #ifdef __SIZEOF_INT128__
310 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)(
311     CppTypeFor<TypeCategory::Real, 8> x) {
312   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
313 }
314 #endif
315 #if LONG_DOUBLE == 80
316 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)(
317     CppTypeFor<TypeCategory::Real, 10> x) {
318   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
319 }
320 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling10_2)(
321     CppTypeFor<TypeCategory::Real, 10> x) {
322   return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
323 }
324 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling10_4)(
325     CppTypeFor<TypeCategory::Real, 10> x) {
326   return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
327 }
328 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling10_8)(
329     CppTypeFor<TypeCategory::Real, 10> x) {
330   return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
331 }
332 #ifdef __SIZEOF_INT128__
333 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)(
334     CppTypeFor<TypeCategory::Real, 10> x) {
335   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
336 }
337 #endif
338 #else
339 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)(
340     CppTypeFor<TypeCategory::Real, 16> x) {
341   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
342 }
343 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling16_2)(
344     CppTypeFor<TypeCategory::Real, 16> x) {
345   return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
346 }
347 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling16_4)(
348     CppTypeFor<TypeCategory::Real, 16> x) {
349   return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
350 }
351 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling16_8)(
352     CppTypeFor<TypeCategory::Real, 16> x) {
353   return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
354 }
355 #ifdef __SIZEOF_INT128__
356 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling16_16)(
357     CppTypeFor<TypeCategory::Real, 16> x) {
358   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
359 }
360 #endif
361 #endif
362 
363 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent4_4)(
364     CppTypeFor<TypeCategory::Real, 4> x) {
365   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
366 }
367 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent4_8)(
368     CppTypeFor<TypeCategory::Real, 4> x) {
369   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
370 }
371 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent8_4)(
372     CppTypeFor<TypeCategory::Real, 8> x) {
373   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
374 }
375 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)(
376     CppTypeFor<TypeCategory::Real, 8> x) {
377   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
378 }
379 #if LONG_DOUBLE == 80
380 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)(
381     CppTypeFor<TypeCategory::Real, 10> x) {
382   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
383 }
384 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)(
385     CppTypeFor<TypeCategory::Real, 10> x) {
386   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
387 }
388 #elif LONG_DOUBLE == 128
389 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)(
390     CppTypeFor<TypeCategory::Real, 16> x) {
391   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
392 }
393 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent16_8)(
394     CppTypeFor<TypeCategory::Real, 16> x) {
395   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
396 }
397 #endif
398 
399 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor4_1)(
400     CppTypeFor<TypeCategory::Real, 4> x) {
401   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
402 }
403 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor4_2)(
404     CppTypeFor<TypeCategory::Real, 4> x) {
405   return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
406 }
407 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor4_4)(
408     CppTypeFor<TypeCategory::Real, 4> x) {
409   return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
410 }
411 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor4_8)(
412     CppTypeFor<TypeCategory::Real, 4> x) {
413   return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
414 }
415 #ifdef __SIZEOF_INT128__
416 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor4_16)(
417     CppTypeFor<TypeCategory::Real, 4> x) {
418   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
419 }
420 #endif
421 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor8_1)(
422     CppTypeFor<TypeCategory::Real, 8> x) {
423   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
424 }
425 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor8_2)(
426     CppTypeFor<TypeCategory::Real, 8> x) {
427   return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
428 }
429 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor8_4)(
430     CppTypeFor<TypeCategory::Real, 8> x) {
431   return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
432 }
433 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor8_8)(
434     CppTypeFor<TypeCategory::Real, 8> x) {
435   return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
436 }
437 #ifdef __SIZEOF_INT128__
438 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)(
439     CppTypeFor<TypeCategory::Real, 8> x) {
440   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
441 }
442 #endif
443 #if LONG_DOUBLE == 80
444 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)(
445     CppTypeFor<TypeCategory::Real, 10> x) {
446   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
447 }
448 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor10_2)(
449     CppTypeFor<TypeCategory::Real, 10> x) {
450   return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
451 }
452 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor10_4)(
453     CppTypeFor<TypeCategory::Real, 10> x) {
454   return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
455 }
456 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor10_8)(
457     CppTypeFor<TypeCategory::Real, 10> x) {
458   return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
459 }
460 #ifdef __SIZEOF_INT128__
461 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)(
462     CppTypeFor<TypeCategory::Real, 10> x) {
463   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
464 }
465 #endif
466 #else
467 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)(
468     CppTypeFor<TypeCategory::Real, 16> x) {
469   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
470 }
471 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor16_2)(
472     CppTypeFor<TypeCategory::Real, 16> x) {
473   return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
474 }
475 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor16_4)(
476     CppTypeFor<TypeCategory::Real, 16> x) {
477   return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
478 }
479 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor16_8)(
480     CppTypeFor<TypeCategory::Real, 16> x) {
481   return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
482 }
483 #ifdef __SIZEOF_INT128__
484 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor16_16)(
485     CppTypeFor<TypeCategory::Real, 16> x) {
486   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
487 }
488 #endif
489 #endif
490 
491 CppTypeFor<TypeCategory::Real, 4> RTNAME(Fraction4)(
492     CppTypeFor<TypeCategory::Real, 4> x) {
493   return Fraction(x);
494 }
495 CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)(
496     CppTypeFor<TypeCategory::Real, 8> x) {
497   return Fraction(x);
498 }
499 #if LONG_DOUBLE == 80
500 CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)(
501     CppTypeFor<TypeCategory::Real, 10> x) {
502   return Fraction(x);
503 }
504 #elif LONG_DOUBLE == 128
505 CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)(
506     CppTypeFor<TypeCategory::Real, 16> x) {
507   return Fraction(x);
508 }
509 #endif
510 
511 bool RTNAME(IsFinite4)(CppTypeFor<TypeCategory::Real, 4> x) {
512   return std::isfinite(x);
513 }
514 bool RTNAME(IsFinite8)(CppTypeFor<TypeCategory::Real, 8> x) {
515   return std::isfinite(x);
516 }
517 #if LONG_DOUBLE == 80
518 bool RTNAME(IsFinite10)(CppTypeFor<TypeCategory::Real, 10> x) {
519   return std::isfinite(x);
520 }
521 #elif LONG_DOUBLE == 128
522 bool RTNAME(IsFinite16)(CppTypeFor<TypeCategory::Real, 16> x) {
523   return std::isfinite(x);
524 }
525 #endif
526 
527 bool RTNAME(IsNaN4)(CppTypeFor<TypeCategory::Real, 4> x) {
528   return std::isnan(x);
529 }
530 bool RTNAME(IsNaN8)(CppTypeFor<TypeCategory::Real, 8> x) {
531   return std::isnan(x);
532 }
533 #if LONG_DOUBLE == 80
534 bool RTNAME(IsNaN10)(CppTypeFor<TypeCategory::Real, 10> x) {
535   return std::isnan(x);
536 }
537 #elif LONG_DOUBLE == 128
538 bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
539   return std::isnan(x);
540 }
541 #endif
542 
543 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
544     CppTypeFor<TypeCategory::Integer, 1> x,
545     CppTypeFor<TypeCategory::Integer, 1> p) {
546   return IntMod<false>(x, p);
547 }
548 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
549     CppTypeFor<TypeCategory::Integer, 2> x,
550     CppTypeFor<TypeCategory::Integer, 2> p) {
551   return IntMod<false>(x, p);
552 }
553 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
554     CppTypeFor<TypeCategory::Integer, 4> x,
555     CppTypeFor<TypeCategory::Integer, 4> p) {
556   return IntMod<false>(x, p);
557 }
558 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
559     CppTypeFor<TypeCategory::Integer, 8> x,
560     CppTypeFor<TypeCategory::Integer, 8> p) {
561   return IntMod<false>(x, p);
562 }
563 #ifdef __SIZEOF_INT128__
564 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
565     CppTypeFor<TypeCategory::Integer, 16> x,
566     CppTypeFor<TypeCategory::Integer, 16> p) {
567   return IntMod<false>(x, p);
568 }
569 #endif
570 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
571     CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
572   return RealMod<false>(x, p);
573 }
574 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
575     CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
576   return RealMod<false>(x, p);
577 }
578 #if LONG_DOUBLE == 80
579 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
580     CppTypeFor<TypeCategory::Real, 10> x,
581     CppTypeFor<TypeCategory::Real, 10> p) {
582   return RealMod<false>(x, p);
583 }
584 #elif LONG_DOUBLE == 128
585 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
586     CppTypeFor<TypeCategory::Real, 16> x,
587     CppTypeFor<TypeCategory::Real, 16> p) {
588   return RealMod<false>(x, p);
589 }
590 #endif
591 
592 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
593     CppTypeFor<TypeCategory::Integer, 1> x,
594     CppTypeFor<TypeCategory::Integer, 1> p) {
595   return IntMod<true>(x, p);
596 }
597 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
598     CppTypeFor<TypeCategory::Integer, 2> x,
599     CppTypeFor<TypeCategory::Integer, 2> p) {
600   return IntMod<true>(x, p);
601 }
602 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
603     CppTypeFor<TypeCategory::Integer, 4> x,
604     CppTypeFor<TypeCategory::Integer, 4> p) {
605   return IntMod<true>(x, p);
606 }
607 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
608     CppTypeFor<TypeCategory::Integer, 8> x,
609     CppTypeFor<TypeCategory::Integer, 8> p) {
610   return IntMod<true>(x, p);
611 }
612 #ifdef __SIZEOF_INT128__
613 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
614     CppTypeFor<TypeCategory::Integer, 16> x,
615     CppTypeFor<TypeCategory::Integer, 16> p) {
616   return IntMod<true>(x, p);
617 }
618 #endif
619 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
620     CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
621   return RealMod<true>(x, p);
622 }
623 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
624     CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
625   return RealMod<true>(x, p);
626 }
627 #if LONG_DOUBLE == 80
628 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
629     CppTypeFor<TypeCategory::Real, 10> x,
630     CppTypeFor<TypeCategory::Real, 10> p) {
631   return RealMod<true>(x, p);
632 }
633 #elif LONG_DOUBLE == 128
634 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
635     CppTypeFor<TypeCategory::Real, 16> x,
636     CppTypeFor<TypeCategory::Real, 16> p) {
637   return RealMod<true>(x, p);
638 }
639 #endif
640 
641 CppTypeFor<TypeCategory::Real, 4> RTNAME(Nearest4)(
642     CppTypeFor<TypeCategory::Real, 4> x, bool positive) {
643   return Nearest<24>(x, positive);
644 }
645 CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
646     CppTypeFor<TypeCategory::Real, 8> x, bool positive) {
647   return Nearest<53>(x, positive);
648 }
649 #if LONG_DOUBLE == 80
650 CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
651     CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
652   return Nearest<64>(x, positive);
653 }
654 #elif LONG_DOUBLE == 128
655 CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
656     CppTypeFor<TypeCategory::Real, 16> x, bool positive) {
657   return Nearest<113>(x, positive);
658 }
659 #endif
660 
661 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
662     CppTypeFor<TypeCategory::Real, 4> x) {
663   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
664 }
665 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint4_2)(
666     CppTypeFor<TypeCategory::Real, 4> x) {
667   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
668 }
669 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint4_4)(
670     CppTypeFor<TypeCategory::Real, 4> x) {
671   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
672 }
673 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint4_8)(
674     CppTypeFor<TypeCategory::Real, 4> x) {
675   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
676 }
677 #ifdef __SIZEOF_INT128__
678 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint4_16)(
679     CppTypeFor<TypeCategory::Real, 4> x) {
680   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
681 }
682 #endif
683 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint8_1)(
684     CppTypeFor<TypeCategory::Real, 8> x) {
685   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
686 }
687 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint8_2)(
688     CppTypeFor<TypeCategory::Real, 8> x) {
689   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
690 }
691 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint8_4)(
692     CppTypeFor<TypeCategory::Real, 8> x) {
693   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
694 }
695 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)(
696     CppTypeFor<TypeCategory::Real, 8> x) {
697   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
698 }
699 #ifdef __SIZEOF_INT128__
700 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
701     CppTypeFor<TypeCategory::Real, 8> x) {
702   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
703 }
704 #endif
705 #if LONG_DOUBLE == 80
706 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
707     CppTypeFor<TypeCategory::Real, 10> x) {
708   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
709 }
710 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)(
711     CppTypeFor<TypeCategory::Real, 10> x) {
712   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
713 }
714 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint10_4)(
715     CppTypeFor<TypeCategory::Real, 10> x) {
716   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
717 }
718 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)(
719     CppTypeFor<TypeCategory::Real, 10> x) {
720   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
721 }
722 #ifdef __SIZEOF_INT128__
723 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
724     CppTypeFor<TypeCategory::Real, 10> x) {
725   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
726 }
727 #endif
728 #else
729 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
730     CppTypeFor<TypeCategory::Real, 16> x) {
731   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
732 }
733 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)(
734     CppTypeFor<TypeCategory::Real, 16> x) {
735   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
736 }
737 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)(
738     CppTypeFor<TypeCategory::Real, 16> x) {
739   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
740 }
741 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)(
742     CppTypeFor<TypeCategory::Real, 16> x) {
743   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
744 }
745 #ifdef __SIZEOF_INT128__
746 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)(
747     CppTypeFor<TypeCategory::Real, 16> x) {
748   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
749 }
750 #endif
751 #endif
752 
753 CppTypeFor<TypeCategory::Real, 4> RTNAME(RRSpacing4)(
754     CppTypeFor<TypeCategory::Real, 4> x) {
755   return RRSpacing<24>(x);
756 }
757 CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
758     CppTypeFor<TypeCategory::Real, 8> x) {
759   return RRSpacing<53>(x);
760 }
761 #if LONG_DOUBLE == 80
762 CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
763     CppTypeFor<TypeCategory::Real, 10> x) {
764   return RRSpacing<64>(x);
765 }
766 #elif LONG_DOUBLE == 128
767 CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
768     CppTypeFor<TypeCategory::Real, 16> x) {
769   return RRSpacing<113>(x);
770 }
771 #endif
772 
773 CppTypeFor<TypeCategory::Real, 4> RTNAME(SetExponent4)(
774     CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
775   return SetExponent(x, p);
776 }
777 CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)(
778     CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
779   return SetExponent(x, p);
780 }
781 #if LONG_DOUBLE == 80
782 CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
783     CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
784   return SetExponent(x, p);
785 }
786 #elif LONG_DOUBLE == 128
787 CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
788     CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
789   return SetExponent(x, p);
790 }
791 #endif
792 
793 CppTypeFor<TypeCategory::Real, 4> RTNAME(Scale4)(
794     CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
795   return Scale(x, p);
796 }
797 CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)(
798     CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
799   return Scale(x, p);
800 }
801 #if LONG_DOUBLE == 80
802 CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
803     CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
804   return Scale(x, p);
805 }
806 #elif LONG_DOUBLE == 128
807 CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
808     CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
809   return Scale(x, p);
810 }
811 #endif
812 
813 CppTypeFor<TypeCategory::Real, 4> RTNAME(Spacing4)(
814     CppTypeFor<TypeCategory::Real, 4> x) {
815   return Spacing<24>(x);
816 }
817 CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
818     CppTypeFor<TypeCategory::Real, 8> x) {
819   return Spacing<53>(x);
820 }
821 #if LONG_DOUBLE == 80
822 CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
823     CppTypeFor<TypeCategory::Real, 10> x) {
824   return Spacing<64>(x);
825 }
826 #elif LONG_DOUBLE == 128
827 CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
828     CppTypeFor<TypeCategory::Real, 16> x) {
829   return Spacing<113>(x);
830 }
831 #endif
832 } // extern "C"
833 } // namespace Fortran::runtime
834