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 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling4_16)(
288     CppTypeFor<TypeCategory::Real, 4> x) {
289   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
290 }
291 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling8_1)(
292     CppTypeFor<TypeCategory::Real, 8> x) {
293   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
294 }
295 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling8_2)(
296     CppTypeFor<TypeCategory::Real, 8> x) {
297   return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
298 }
299 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling8_4)(
300     CppTypeFor<TypeCategory::Real, 8> x) {
301   return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
302 }
303 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling8_8)(
304     CppTypeFor<TypeCategory::Real, 8> x) {
305   return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
306 }
307 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)(
308     CppTypeFor<TypeCategory::Real, 8> x) {
309   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
310 }
311 #if LONG_DOUBLE == 80
312 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)(
313     CppTypeFor<TypeCategory::Real, 10> x) {
314   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
315 }
316 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling10_2)(
317     CppTypeFor<TypeCategory::Real, 10> x) {
318   return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
319 }
320 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling10_4)(
321     CppTypeFor<TypeCategory::Real, 10> x) {
322   return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
323 }
324 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling10_8)(
325     CppTypeFor<TypeCategory::Real, 10> x) {
326   return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
327 }
328 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)(
329     CppTypeFor<TypeCategory::Real, 10> x) {
330   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
331 }
332 #else
333 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)(
334     CppTypeFor<TypeCategory::Real, 16> x) {
335   return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x);
336 }
337 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling16_2)(
338     CppTypeFor<TypeCategory::Real, 16> x) {
339   return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x);
340 }
341 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling16_4)(
342     CppTypeFor<TypeCategory::Real, 16> x) {
343   return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x);
344 }
345 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling16_8)(
346     CppTypeFor<TypeCategory::Real, 16> x) {
347   return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x);
348 }
349 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling16_16)(
350     CppTypeFor<TypeCategory::Real, 16> x) {
351   return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x);
352 }
353 #endif
354 
355 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent4_4)(
356     CppTypeFor<TypeCategory::Real, 4> x) {
357   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
358 }
359 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent4_8)(
360     CppTypeFor<TypeCategory::Real, 4> x) {
361   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
362 }
363 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent8_4)(
364     CppTypeFor<TypeCategory::Real, 8> x) {
365   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
366 }
367 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)(
368     CppTypeFor<TypeCategory::Real, 8> x) {
369   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
370 }
371 #if LONG_DOUBLE == 80
372 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)(
373     CppTypeFor<TypeCategory::Real, 10> x) {
374   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
375 }
376 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)(
377     CppTypeFor<TypeCategory::Real, 10> x) {
378   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
379 }
380 #elif LONG_DOUBLE == 128
381 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)(
382     CppTypeFor<TypeCategory::Real, 16> x) {
383   return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x);
384 }
385 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent16_8)(
386     CppTypeFor<TypeCategory::Real, 16> x) {
387   return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x);
388 }
389 #endif
390 
391 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor4_1)(
392     CppTypeFor<TypeCategory::Real, 4> x) {
393   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
394 }
395 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor4_2)(
396     CppTypeFor<TypeCategory::Real, 4> x) {
397   return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
398 }
399 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor4_4)(
400     CppTypeFor<TypeCategory::Real, 4> x) {
401   return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
402 }
403 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor4_8)(
404     CppTypeFor<TypeCategory::Real, 4> x) {
405   return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
406 }
407 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor4_16)(
408     CppTypeFor<TypeCategory::Real, 4> x) {
409   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
410 }
411 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor8_1)(
412     CppTypeFor<TypeCategory::Real, 8> x) {
413   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
414 }
415 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor8_2)(
416     CppTypeFor<TypeCategory::Real, 8> x) {
417   return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
418 }
419 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor8_4)(
420     CppTypeFor<TypeCategory::Real, 8> x) {
421   return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
422 }
423 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor8_8)(
424     CppTypeFor<TypeCategory::Real, 8> x) {
425   return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
426 }
427 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)(
428     CppTypeFor<TypeCategory::Real, 8> x) {
429   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
430 }
431 #if LONG_DOUBLE == 80
432 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)(
433     CppTypeFor<TypeCategory::Real, 10> x) {
434   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
435 }
436 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor10_2)(
437     CppTypeFor<TypeCategory::Real, 10> x) {
438   return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
439 }
440 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor10_4)(
441     CppTypeFor<TypeCategory::Real, 10> x) {
442   return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
443 }
444 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor10_8)(
445     CppTypeFor<TypeCategory::Real, 10> x) {
446   return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
447 }
448 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)(
449     CppTypeFor<TypeCategory::Real, 10> x) {
450   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
451 }
452 #else
453 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)(
454     CppTypeFor<TypeCategory::Real, 16> x) {
455   return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x);
456 }
457 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor16_2)(
458     CppTypeFor<TypeCategory::Real, 16> x) {
459   return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x);
460 }
461 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor16_4)(
462     CppTypeFor<TypeCategory::Real, 16> x) {
463   return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x);
464 }
465 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor16_8)(
466     CppTypeFor<TypeCategory::Real, 16> x) {
467   return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x);
468 }
469 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor16_16)(
470     CppTypeFor<TypeCategory::Real, 16> x) {
471   return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x);
472 }
473 #endif
474 
475 CppTypeFor<TypeCategory::Real, 4> RTNAME(Fraction4)(
476     CppTypeFor<TypeCategory::Real, 4> x) {
477   return Fraction(x);
478 }
479 CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)(
480     CppTypeFor<TypeCategory::Real, 8> x) {
481   return Fraction(x);
482 }
483 #if LONG_DOUBLE == 80
484 CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)(
485     CppTypeFor<TypeCategory::Real, 10> x) {
486   return Fraction(x);
487 }
488 #elif LONG_DOUBLE == 128
489 CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)(
490     CppTypeFor<TypeCategory::Real, 16> x) {
491   return Fraction(x);
492 }
493 #endif
494 
495 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
496     CppTypeFor<TypeCategory::Integer, 1> x,
497     CppTypeFor<TypeCategory::Integer, 1> p) {
498   return IntMod<false>(x, p);
499 }
500 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
501     CppTypeFor<TypeCategory::Integer, 2> x,
502     CppTypeFor<TypeCategory::Integer, 2> p) {
503   return IntMod<false>(x, p);
504 }
505 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
506     CppTypeFor<TypeCategory::Integer, 4> x,
507     CppTypeFor<TypeCategory::Integer, 4> p) {
508   return IntMod<false>(x, p);
509 }
510 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
511     CppTypeFor<TypeCategory::Integer, 8> x,
512     CppTypeFor<TypeCategory::Integer, 8> p) {
513   return IntMod<false>(x, p);
514 }
515 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
516     CppTypeFor<TypeCategory::Integer, 16> x,
517     CppTypeFor<TypeCategory::Integer, 16> p) {
518   return IntMod<false>(x, p);
519 }
520 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
521     CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
522   return RealMod<false>(x, p);
523 }
524 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
525     CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
526   return RealMod<false>(x, p);
527 }
528 #if LONG_DOUBLE == 80
529 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
530     CppTypeFor<TypeCategory::Real, 10> x,
531     CppTypeFor<TypeCategory::Real, 10> p) {
532   return RealMod<false>(x, p);
533 }
534 #elif LONG_DOUBLE == 128
535 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
536     CppTypeFor<TypeCategory::Real, 16> x,
537     CppTypeFor<TypeCategory::Real, 16> p) {
538   return RealMod<false>(x, p);
539 }
540 #endif
541 
542 CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
543     CppTypeFor<TypeCategory::Integer, 1> x,
544     CppTypeFor<TypeCategory::Integer, 1> p) {
545   return IntMod<true>(x, p);
546 }
547 CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
548     CppTypeFor<TypeCategory::Integer, 2> x,
549     CppTypeFor<TypeCategory::Integer, 2> p) {
550   return IntMod<true>(x, p);
551 }
552 CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
553     CppTypeFor<TypeCategory::Integer, 4> x,
554     CppTypeFor<TypeCategory::Integer, 4> p) {
555   return IntMod<true>(x, p);
556 }
557 CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
558     CppTypeFor<TypeCategory::Integer, 8> x,
559     CppTypeFor<TypeCategory::Integer, 8> p) {
560   return IntMod<true>(x, p);
561 }
562 CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
563     CppTypeFor<TypeCategory::Integer, 16> x,
564     CppTypeFor<TypeCategory::Integer, 16> p) {
565   return IntMod<true>(x, p);
566 }
567 CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
568     CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) {
569   return RealMod<true>(x, p);
570 }
571 CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
572     CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) {
573   return RealMod<true>(x, p);
574 }
575 #if LONG_DOUBLE == 80
576 CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
577     CppTypeFor<TypeCategory::Real, 10> x,
578     CppTypeFor<TypeCategory::Real, 10> p) {
579   return RealMod<true>(x, p);
580 }
581 #elif LONG_DOUBLE == 128
582 CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
583     CppTypeFor<TypeCategory::Real, 16> x,
584     CppTypeFor<TypeCategory::Real, 16> p) {
585   return RealMod<true>(x, p);
586 }
587 #endif
588 
589 CppTypeFor<TypeCategory::Real, 4> RTNAME(Nearest4)(
590     CppTypeFor<TypeCategory::Real, 4> x, bool positive) {
591   return Nearest<24>(x, positive);
592 }
593 CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)(
594     CppTypeFor<TypeCategory::Real, 8> x, bool positive) {
595   return Nearest<53>(x, positive);
596 }
597 #if LONG_DOUBLE == 80
598 CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)(
599     CppTypeFor<TypeCategory::Real, 10> x, bool positive) {
600   return Nearest<64>(x, positive);
601 }
602 #elif LONG_DOUBLE == 128
603 CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)(
604     CppTypeFor<TypeCategory::Real, 16> x, bool positive) {
605   return Nearest<113>(x, positive);
606 }
607 #endif
608 
609 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)(
610     CppTypeFor<TypeCategory::Real, 4> x) {
611   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
612 }
613 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint4_2)(
614     CppTypeFor<TypeCategory::Real, 4> x) {
615   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
616 }
617 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint4_4)(
618     CppTypeFor<TypeCategory::Real, 4> x) {
619   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
620 }
621 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint4_8)(
622     CppTypeFor<TypeCategory::Real, 4> x) {
623   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
624 }
625 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint4_16)(
626     CppTypeFor<TypeCategory::Real, 4> x) {
627   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
628 }
629 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint8_1)(
630     CppTypeFor<TypeCategory::Real, 8> x) {
631   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
632 }
633 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint8_2)(
634     CppTypeFor<TypeCategory::Real, 8> x) {
635   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
636 }
637 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint8_4)(
638     CppTypeFor<TypeCategory::Real, 8> x) {
639   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
640 }
641 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)(
642     CppTypeFor<TypeCategory::Real, 8> x) {
643   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
644 }
645 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)(
646     CppTypeFor<TypeCategory::Real, 8> x) {
647   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
648 }
649 #if LONG_DOUBLE == 80
650 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)(
651     CppTypeFor<TypeCategory::Real, 10> x) {
652   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
653 }
654 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)(
655     CppTypeFor<TypeCategory::Real, 10> x) {
656   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
657 }
658 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint10_4)(
659     CppTypeFor<TypeCategory::Real, 10> x) {
660   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
661 }
662 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)(
663     CppTypeFor<TypeCategory::Real, 10> x) {
664   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
665 }
666 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)(
667     CppTypeFor<TypeCategory::Real, 10> x) {
668   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
669 }
670 #else
671 CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)(
672     CppTypeFor<TypeCategory::Real, 16> x) {
673   return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x);
674 }
675 CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)(
676     CppTypeFor<TypeCategory::Real, 16> x) {
677   return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x);
678 }
679 CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)(
680     CppTypeFor<TypeCategory::Real, 16> x) {
681   return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x);
682 }
683 CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)(
684     CppTypeFor<TypeCategory::Real, 16> x) {
685   return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x);
686 }
687 CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)(
688     CppTypeFor<TypeCategory::Real, 16> x) {
689   return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x);
690 }
691 #endif
692 
693 CppTypeFor<TypeCategory::Real, 4> RTNAME(RRSpacing4)(
694     CppTypeFor<TypeCategory::Real, 4> x) {
695   return RRSpacing<24>(x);
696 }
697 CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)(
698     CppTypeFor<TypeCategory::Real, 8> x) {
699   return RRSpacing<53>(x);
700 }
701 #if LONG_DOUBLE == 80
702 CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)(
703     CppTypeFor<TypeCategory::Real, 10> x) {
704   return RRSpacing<64>(x);
705 }
706 #elif LONG_DOUBLE == 128
707 CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)(
708     CppTypeFor<TypeCategory::Real, 16> x) {
709   return RRSpacing<113>(x);
710 }
711 #endif
712 
713 CppTypeFor<TypeCategory::Real, 4> RTNAME(SetExponent4)(
714     CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
715   return SetExponent(x, p);
716 }
717 CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)(
718     CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
719   return SetExponent(x, p);
720 }
721 #if LONG_DOUBLE == 80
722 CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)(
723     CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
724   return SetExponent(x, p);
725 }
726 #elif LONG_DOUBLE == 128
727 CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)(
728     CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
729   return SetExponent(x, p);
730 }
731 #endif
732 
733 CppTypeFor<TypeCategory::Real, 4> RTNAME(Scale4)(
734     CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) {
735   return Scale(x, p);
736 }
737 CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)(
738     CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) {
739   return Scale(x, p);
740 }
741 #if LONG_DOUBLE == 80
742 CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)(
743     CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) {
744   return Scale(x, p);
745 }
746 #elif LONG_DOUBLE == 128
747 CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)(
748     CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) {
749   return Scale(x, p);
750 }
751 #endif
752 
753 CppTypeFor<TypeCategory::Real, 4> RTNAME(Spacing4)(
754     CppTypeFor<TypeCategory::Real, 4> x) {
755   return Spacing<24>(x);
756 }
757 CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)(
758     CppTypeFor<TypeCategory::Real, 8> x) {
759   return Spacing<53>(x);
760 }
761 #if LONG_DOUBLE == 80
762 CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)(
763     CppTypeFor<TypeCategory::Real, 10> x) {
764   return Spacing<64>(x);
765 }
766 #elif LONG_DOUBLE == 128
767 CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)(
768     CppTypeFor<TypeCategory::Real, 16> x) {
769   return Spacing<113>(x);
770 }
771 #endif
772 } // extern "C"
773 } // namespace Fortran::runtime
774