1 //===-- runtime/numeric.cpp -------------------------------------*- C++ -*-===//
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 "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)};
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 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
512     CppTypeFor<TypeCategory::Integer, 1> x,
513     CppTypeFor<TypeCategory::Integer, 1> p) {
514   return IntMod<false>(x, p);
515 }
516 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
517     CppTypeFor<TypeCategory::Integer, 2> x,
518     CppTypeFor<TypeCategory::Integer, 2> p) {
519   return IntMod<false>(x, p);
520 }
521 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
522     CppTypeFor<TypeCategory::Integer, 4> x,
523     CppTypeFor<TypeCategory::Integer, 4> p) {
524   return IntMod<false>(x, p);
525 }
526 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
527     CppTypeFor<TypeCategory::Integer, 8> x,
528     CppTypeFor<TypeCategory::Integer, 8> p) {
529   return IntMod<false>(x, p);
530 }
531 #ifdef __SIZEOF_INT128__
532 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
533     CppTypeFor<TypeCategory::Integer, 16> x,
534     CppTypeFor<TypeCategory::Integer, 16> p) {
535   return IntMod<false>(x, p);
536 }
537 #endif
538 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
539     CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
540   return RealMod<false>(x, p);
541 }
542 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
543     CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
544   return RealMod<false>(x, p);
545 }
546 #if LONG_DOUBLE == 80
547 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
548     CppTypeFor<TypeCategory::Real, 10> x,
549     CppTypeFor<TypeCategory::Real, 10> p) {
550   return RealMod<false>(x, p);
551 }
552 #elif LONG_DOUBLE == 128
553 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
554     CppTypeFor<TypeCategory::Real, 16> x,
555     CppTypeFor<TypeCategory::Real, 16> p) {
556   return RealMod<false>(x, p);
557 }
558 #endif
559 
560 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
561     CppTypeFor<TypeCategory::Integer, 1> x,
562     CppTypeFor<TypeCategory::Integer, 1> p) {
563   return IntMod<true>(x, p);
564 }
565 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
566     CppTypeFor<TypeCategory::Integer, 2> x,
567     CppTypeFor<TypeCategory::Integer, 2> p) {
568   return IntMod<true>(x, p);
569 }
570 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
571     CppTypeFor<TypeCategory::Integer, 4> x,
572     CppTypeFor<TypeCategory::Integer, 4> p) {
573   return IntMod<true>(x, p);
574 }
575 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
576     CppTypeFor<TypeCategory::Integer, 8> x,
577     CppTypeFor<TypeCategory::Integer, 8> p) {
578   return IntMod<true>(x, p);
579 }
580 #ifdef __SIZEOF_INT128__
581 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
582     CppTypeFor<TypeCategory::Integer, 16> x,
583     CppTypeFor<TypeCategory::Integer, 16> p) {
584   return IntMod<true>(x, p);
585 }
586 #endif
587 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
588     CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
589   return RealMod<true>(x, p);
590 }
591 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
592     CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
593   return RealMod<true>(x, p);
594 }
595 #if LONG_DOUBLE == 80
596 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
597     CppTypeFor<TypeCategory::Real, 10> x,
598     CppTypeFor<TypeCategory::Real, 10> p) {
599   return RealMod<true>(x, p);
600 }
601 #elif LONG_DOUBLE == 128
602 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
603     CppTypeFor<TypeCategory::Real, 16> x,
604     CppTypeFor<TypeCategory::Real, 16> p) {
605   return RealMod<true>(x, p);
606 }
607 #endif
608 
609 CppTypeFor<TypeCategory::Real, 4> RTNAME(Nearest4)(
610     CppTypeFor<TypeCategory::Real, 4> x, bool positive) {
611   return Nearest<24>(x, positive);
612 }
613 CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
614     CppTypeFor<TypeCategory::Real, 8> x, bool positive) {
615   return Nearest<53>(x, positive);
616 }
617 #if LONG_DOUBLE == 80
618 CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
619     CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
620   return Nearest<64>(x, positive);
621 }
622 #elif LONG_DOUBLE == 128
623 CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
624     CppTypeFor<TypeCategory::Real, 16> x, bool positive) {
625   return Nearest<113>(x, positive);
626 }
627 #endif
628 
629 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
630     CppTypeFor<TypeCategory::Real, 4> x) {
631   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
632 }
633 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint4_2)(
634     CppTypeFor<TypeCategory::Real, 4> x) {
635   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
636 }
637 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint4_4)(
638     CppTypeFor<TypeCategory::Real, 4> x) {
639   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
640 }
641 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint4_8)(
642     CppTypeFor<TypeCategory::Real, 4> x) {
643   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
644 }
645 #ifdef __SIZEOF_INT128__
646 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint4_16)(
647     CppTypeFor<TypeCategory::Real, 4> x) {
648   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
649 }
650 #endif
651 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint8_1)(
652     CppTypeFor<TypeCategory::Real, 8> x) {
653   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
654 }
655 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint8_2)(
656     CppTypeFor<TypeCategory::Real, 8> x) {
657   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
658 }
659 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint8_4)(
660     CppTypeFor<TypeCategory::Real, 8> x) {
661   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
662 }
663 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)(
664     CppTypeFor<TypeCategory::Real, 8> x) {
665   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
666 }
667 #ifdef __SIZEOF_INT128__
668 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
669     CppTypeFor<TypeCategory::Real, 8> x) {
670   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
671 }
672 #endif
673 #if LONG_DOUBLE == 80
674 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
675     CppTypeFor<TypeCategory::Real, 10> x) {
676   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
677 }
678 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)(
679     CppTypeFor<TypeCategory::Real, 10> x) {
680   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
681 }
682 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint10_4)(
683     CppTypeFor<TypeCategory::Real, 10> x) {
684   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
685 }
686 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)(
687     CppTypeFor<TypeCategory::Real, 10> x) {
688   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
689 }
690 #ifdef __SIZEOF_INT128__
691 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
692     CppTypeFor<TypeCategory::Real, 10> x) {
693   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
694 }
695 #endif
696 #else
697 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
698     CppTypeFor<TypeCategory::Real, 16> x) {
699   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
700 }
701 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)(
702     CppTypeFor<TypeCategory::Real, 16> x) {
703   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
704 }
705 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)(
706     CppTypeFor<TypeCategory::Real, 16> x) {
707   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
708 }
709 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)(
710     CppTypeFor<TypeCategory::Real, 16> x) {
711   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
712 }
713 #ifdef __SIZEOF_INT128__
714 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)(
715     CppTypeFor<TypeCategory::Real, 16> x) {
716   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
717 }
718 #endif
719 #endif
720 
721 CppTypeFor<TypeCategory::Real, 4> RTNAME(RRSpacing4)(
722     CppTypeFor<TypeCategory::Real, 4> x) {
723   return RRSpacing<24>(x);
724 }
725 CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
726     CppTypeFor<TypeCategory::Real, 8> x) {
727   return RRSpacing<53>(x);
728 }
729 #if LONG_DOUBLE == 80
730 CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
731     CppTypeFor<TypeCategory::Real, 10> x) {
732   return RRSpacing<64>(x);
733 }
734 #elif LONG_DOUBLE == 128
735 CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
736     CppTypeFor<TypeCategory::Real, 16> x) {
737   return RRSpacing<113>(x);
738 }
739 #endif
740 
741 CppTypeFor<TypeCategory::Real, 4> RTNAME(SetExponent4)(
742     CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
743   return SetExponent(x, p);
744 }
745 CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)(
746     CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
747   return SetExponent(x, p);
748 }
749 #if LONG_DOUBLE == 80
750 CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
751     CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
752   return SetExponent(x, p);
753 }
754 #elif LONG_DOUBLE == 128
755 CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
756     CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
757   return SetExponent(x, p);
758 }
759 #endif
760 
761 CppTypeFor<TypeCategory::Real, 4> RTNAME(Scale4)(
762     CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
763   return Scale(x, p);
764 }
765 CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)(
766     CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
767   return Scale(x, p);
768 }
769 #if LONG_DOUBLE == 80
770 CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
771     CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
772   return Scale(x, p);
773 }
774 #elif LONG_DOUBLE == 128
775 CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
776     CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
777   return Scale(x, p);
778 }
779 #endif
780 
781 CppTypeFor<TypeCategory::Real, 4> RTNAME(Spacing4)(
782     CppTypeFor<TypeCategory::Real, 4> x) {
783   return Spacing<24>(x);
784 }
785 CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
786     CppTypeFor<TypeCategory::Real, 8> x) {
787   return Spacing<53>(x);
788 }
789 #if LONG_DOUBLE == 80
790 CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
791     CppTypeFor<TypeCategory::Real, 10> x) {
792   return Spacing<64>(x);
793 }
794 #elif LONG_DOUBLE == 128
795 CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
796     CppTypeFor<TypeCategory::Real, 16> x) {
797   return Spacing<113>(x);
798 }
799 #endif
800 } // extern "C"
801 } // namespace Fortran::runtime
802