| //===-- runtime/numeric.cpp -----------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "flang/Runtime/numeric.h" |
| #include "flang/Common/long-double.h" |
| #include <climits> |
| #include <cmath> |
| #include <limits> |
| |
| namespace Fortran::runtime { |
| |
| // AINT |
| template <typename RESULT, typename ARG> inline RESULT Aint(ARG x) { |
| return std::trunc(x); |
| } |
| |
| // ANINT & NINT |
| template <typename RESULT, typename ARG> inline RESULT Anint(ARG x) { |
| if (x >= 0) { |
| return std::trunc(x + ARG{0.5}); |
| } else { |
| return std::trunc(x - ARG{0.5}); |
| } |
| } |
| |
| // CEILING & FLOOR (16.9.43, .79) |
| template <typename RESULT, typename ARG> inline RESULT Ceiling(ARG x) { |
| return std::ceil(x); |
| } |
| template <typename RESULT, typename ARG> inline RESULT Floor(ARG x) { |
| return std::floor(x); |
| } |
| |
| // EXPONENT (16.9.75) |
| template <typename RESULT, typename ARG> inline RESULT Exponent(ARG x) { |
| if (std::isinf(x) || std::isnan(x)) { |
| return std::numeric_limits<RESULT>::max(); // +/-Inf, NaN -> HUGE(0) |
| } else if (x == 0) { |
| return 0; // 0 -> 0 |
| } else { |
| return std::ilogb(x) + 1; |
| } |
| } |
| |
| // FRACTION (16.9.80) |
| template <typename T> inline T Fraction(T x) { |
| if (std::isnan(x)) { |
| return x; // NaN -> same NaN |
| } else if (std::isinf(x)) { |
| return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN |
| } else if (x == 0) { |
| return 0; // 0 -> 0 |
| } else { |
| int ignoredExp; |
| return std::frexp(x, &ignoredExp); |
| } |
| } |
| |
| // MOD & MODULO (16.9.135, .136) |
| template <bool IS_MODULO, typename T> inline T IntMod(T x, T p) { |
| auto mod{x - (x / p) * p}; |
| if (IS_MODULO && (x > 0) != (p > 0)) { |
| mod += p; |
| } |
| return mod; |
| } |
| template <bool IS_MODULO, typename T> inline T RealMod(T x, T p) { |
| if constexpr (IS_MODULO) { |
| return x - std::floor(x / p) * p; |
| } else { |
| return x - std::trunc(x / p) * p; |
| } |
| } |
| |
| // RRSPACING (16.9.164) |
| template <int PREC, typename T> inline T RRSpacing(T x) { |
| if (std::isnan(x)) { |
| return x; // NaN -> same NaN |
| } else if (std::isinf(x)) { |
| return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN |
| } else if (x == 0) { |
| return 0; // 0 -> 0 |
| } else { |
| return std::ldexp(std::abs(x), PREC - (std::ilogb(x) + 1)); |
| } |
| } |
| |
| // SCALE (16.9.166) |
| template <typename T> inline T Scale(T x, std::int64_t p) { |
| auto ip{static_cast<int>(p)}; |
| if (ip != p) { |
| ip = p < 0 ? std::numeric_limits<int>::min() |
| : std::numeric_limits<int>::max(); |
| } |
| return std::ldexp(x, p); // x*2**p |
| } |
| |
| // SET_EXPONENT (16.9.171) |
| template <typename T> inline T SetExponent(T x, std::int64_t p) { |
| if (std::isnan(x)) { |
| return x; // NaN -> same NaN |
| } else if (std::isinf(x)) { |
| return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN |
| } else if (x == 0) { |
| return 0; // 0 -> 0 |
| } else { |
| int expo{std::ilogb(x) + 1}; |
| auto ip{static_cast<int>(p - expo)}; |
| if (ip != p - expo) { |
| ip = p < 0 ? std::numeric_limits<int>::min() |
| : std::numeric_limits<int>::max(); |
| } |
| return std::ldexp(x, ip); // x*2**(p-e) |
| } |
| } |
| |
| // SPACING (16.9.180) |
| template <int PREC, typename T> inline T Spacing(T x) { |
| if (std::isnan(x)) { |
| return x; // NaN -> same NaN |
| } else if (std::isinf(x)) { |
| return std::numeric_limits<T>::quiet_NaN(); // +/-Inf -> NaN |
| } else if (x == 0) { |
| // The standard-mandated behavior seems broken, since TINY() can't be |
| // subnormal. |
| return std::numeric_limits<T>::min(); // 0 -> TINY(x) |
| } else { |
| return std::ldexp( |
| static_cast<T>(1.0), std::ilogb(x) + 1 - PREC); // 2**(e-p) |
| } |
| } |
| |
| // NEAREST (16.9.139) |
| template <int PREC, typename T> inline T Nearest(T x, bool positive) { |
| auto spacing{Spacing<PREC>(x)}; |
| if (x == 0) { |
| auto least{std::numeric_limits<T>::denorm_min()}; |
| return positive ? least : -least; |
| } else { |
| return positive ? x + spacing : x - spacing; |
| } |
| } |
| |
| extern "C" { |
| |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint4_4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint4_8)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 8>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint8_4)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint8_8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 8>>(x); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint4_10)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 10>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint8_10)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 10>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint10_4)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint10_8)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 8>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Aint10_10)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 10>>(x); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint4_16)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 16>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint8_16)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 16>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Aint16_4)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Aint16_8)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 8>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Aint16_16)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Aint<CppTypeFor<TypeCategory::Real, 16>>(x); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint4_4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint4_8)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 8>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint8_4)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint8_8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 8>>(x); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint4_10)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 10>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint8_10)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 10>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint10_4)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint10_8)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 8>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Anint10_10)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 10>>(x); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint4_16)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 16>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint8_16)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 16>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Anint16_4)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Anint16_8)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 8>>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Anint16_16)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Anint<CppTypeFor<TypeCategory::Real, 16>>(x); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling4_1)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling4_2)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling4_4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling4_8)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling4_16)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling8_1)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling8_2)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling8_4)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling8_8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling8_16)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling10_1)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling10_2)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling10_4)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling10_8)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling10_16)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #else |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Ceiling16_1)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Ceiling16_2)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Ceiling16_4)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Ceiling16_8)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Ceiling16_16)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Ceiling<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #endif |
| |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent4_4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent4_8)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent8_4)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent8_8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent10_4)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent10_8)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Exponent16_4)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Exponent<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Exponent16_8)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Exponent<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor4_1)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor4_2)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor4_4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor4_8)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor4_16)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor8_1)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor8_2)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor8_4)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor8_8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor8_16)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor10_1)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor10_2)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor10_4)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor10_8)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor10_16)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #else |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Floor16_1)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Floor16_2)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Floor16_4)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Floor16_8)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Floor16_16)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Floor<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #endif |
| |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Fraction4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Fraction(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Fraction8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Fraction(x); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Fraction10)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Fraction(x); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Fraction16)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Fraction(x); |
| } |
| #endif |
| |
| bool RTNAME(IsFinite4)(CppTypeFor<TypeCategory::Real, 4> x) { |
| return std::isfinite(x); |
| } |
| bool RTNAME(IsFinite8)(CppTypeFor<TypeCategory::Real, 8> x) { |
| return std::isfinite(x); |
| } |
| #if LONG_DOUBLE == 80 |
| bool RTNAME(IsFinite10)(CppTypeFor<TypeCategory::Real, 10> x) { |
| return std::isfinite(x); |
| } |
| #elif LONG_DOUBLE == 128 |
| bool RTNAME(IsFinite16)(CppTypeFor<TypeCategory::Real, 16> x) { |
| return std::isfinite(x); |
| } |
| #endif |
| |
| bool RTNAME(IsNaN4)(CppTypeFor<TypeCategory::Real, 4> x) { |
| return std::isnan(x); |
| } |
| bool RTNAME(IsNaN8)(CppTypeFor<TypeCategory::Real, 8> x) { |
| return std::isnan(x); |
| } |
| #if LONG_DOUBLE == 80 |
| bool RTNAME(IsNaN10)(CppTypeFor<TypeCategory::Real, 10> x) { |
| return std::isnan(x); |
| } |
| #elif LONG_DOUBLE == 128 |
| bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) { |
| return std::isnan(x); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)( |
| CppTypeFor<TypeCategory::Integer, 1> x, |
| CppTypeFor<TypeCategory::Integer, 1> p) { |
| return IntMod<false>(x, p); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)( |
| CppTypeFor<TypeCategory::Integer, 2> x, |
| CppTypeFor<TypeCategory::Integer, 2> p) { |
| return IntMod<false>(x, p); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)( |
| CppTypeFor<TypeCategory::Integer, 4> x, |
| CppTypeFor<TypeCategory::Integer, 4> p) { |
| return IntMod<false>(x, p); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)( |
| CppTypeFor<TypeCategory::Integer, 8> x, |
| CppTypeFor<TypeCategory::Integer, 8> p) { |
| return IntMod<false>(x, p); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)( |
| CppTypeFor<TypeCategory::Integer, 16> x, |
| CppTypeFor<TypeCategory::Integer, 16> p) { |
| return IntMod<false>(x, p); |
| } |
| #endif |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)( |
| CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) { |
| return RealMod<false>(x, p); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)( |
| CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) { |
| return RealMod<false>(x, p); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)( |
| CppTypeFor<TypeCategory::Real, 10> x, |
| CppTypeFor<TypeCategory::Real, 10> p) { |
| return RealMod<false>(x, p); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)( |
| CppTypeFor<TypeCategory::Real, 16> x, |
| CppTypeFor<TypeCategory::Real, 16> p) { |
| return RealMod<false>(x, p); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)( |
| CppTypeFor<TypeCategory::Integer, 1> x, |
| CppTypeFor<TypeCategory::Integer, 1> p) { |
| return IntMod<true>(x, p); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)( |
| CppTypeFor<TypeCategory::Integer, 2> x, |
| CppTypeFor<TypeCategory::Integer, 2> p) { |
| return IntMod<true>(x, p); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)( |
| CppTypeFor<TypeCategory::Integer, 4> x, |
| CppTypeFor<TypeCategory::Integer, 4> p) { |
| return IntMod<true>(x, p); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)( |
| CppTypeFor<TypeCategory::Integer, 8> x, |
| CppTypeFor<TypeCategory::Integer, 8> p) { |
| return IntMod<true>(x, p); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)( |
| CppTypeFor<TypeCategory::Integer, 16> x, |
| CppTypeFor<TypeCategory::Integer, 16> p) { |
| return IntMod<true>(x, p); |
| } |
| #endif |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)( |
| CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) { |
| return RealMod<true>(x, p); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)( |
| CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) { |
| return RealMod<true>(x, p); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)( |
| CppTypeFor<TypeCategory::Real, 10> x, |
| CppTypeFor<TypeCategory::Real, 10> p) { |
| return RealMod<true>(x, p); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)( |
| CppTypeFor<TypeCategory::Real, 16> x, |
| CppTypeFor<TypeCategory::Real, 16> p) { |
| return RealMod<true>(x, p); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Nearest4)( |
| CppTypeFor<TypeCategory::Real, 4> x, bool positive) { |
| return Nearest<24>(x, positive); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Nearest8)( |
| CppTypeFor<TypeCategory::Real, 8> x, bool positive) { |
| return Nearest<53>(x, positive); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Nearest10)( |
| CppTypeFor<TypeCategory::Real, 10> x, bool positive) { |
| return Nearest<64>(x, positive); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Nearest16)( |
| CppTypeFor<TypeCategory::Real, 16> x, bool positive) { |
| return Nearest<113>(x, positive); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint4_1)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint4_2)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint4_4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint4_8)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint4_16)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint8_1)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint8_2)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint8_4)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint8_8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint8_16)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint10_1)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint10_2)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint10_4)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint10_8)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint10_16)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #else |
| CppTypeFor<TypeCategory::Integer, 1> RTNAME(Nint16_1)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 1>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 2> RTNAME(Nint16_2)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 2>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 4> RTNAME(Nint16_4)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 4>>(x); |
| } |
| CppTypeFor<TypeCategory::Integer, 8> RTNAME(Nint16_8)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 8>>(x); |
| } |
| #ifdef __SIZEOF_INT128__ |
| CppTypeFor<TypeCategory::Integer, 16> RTNAME(Nint16_16)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Anint<CppTypeFor<TypeCategory::Integer, 16>>(x); |
| } |
| #endif |
| #endif |
| |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(RRSpacing4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return RRSpacing<24>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(RRSpacing8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return RRSpacing<53>(x); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(RRSpacing10)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return RRSpacing<64>(x); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(RRSpacing16)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return RRSpacing<113>(x); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(SetExponent4)( |
| CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) { |
| return SetExponent(x, p); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(SetExponent8)( |
| CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) { |
| return SetExponent(x, p); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(SetExponent10)( |
| CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) { |
| return SetExponent(x, p); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(SetExponent16)( |
| CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) { |
| return SetExponent(x, p); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Scale4)( |
| CppTypeFor<TypeCategory::Real, 4> x, std::int64_t p) { |
| return Scale(x, p); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Scale8)( |
| CppTypeFor<TypeCategory::Real, 8> x, std::int64_t p) { |
| return Scale(x, p); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Scale10)( |
| CppTypeFor<TypeCategory::Real, 10> x, std::int64_t p) { |
| return Scale(x, p); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Scale16)( |
| CppTypeFor<TypeCategory::Real, 16> x, std::int64_t p) { |
| return Scale(x, p); |
| } |
| #endif |
| |
| CppTypeFor<TypeCategory::Real, 4> RTNAME(Spacing4)( |
| CppTypeFor<TypeCategory::Real, 4> x) { |
| return Spacing<24>(x); |
| } |
| CppTypeFor<TypeCategory::Real, 8> RTNAME(Spacing8)( |
| CppTypeFor<TypeCategory::Real, 8> x) { |
| return Spacing<53>(x); |
| } |
| #if LONG_DOUBLE == 80 |
| CppTypeFor<TypeCategory::Real, 10> RTNAME(Spacing10)( |
| CppTypeFor<TypeCategory::Real, 10> x) { |
| return Spacing<64>(x); |
| } |
| #elif LONG_DOUBLE == 128 |
| CppTypeFor<TypeCategory::Real, 16> RTNAME(Spacing16)( |
| CppTypeFor<TypeCategory::Real, 16> x) { |
| return Spacing<113>(x); |
| } |
| #endif |
| } // extern "C" |
| } // namespace Fortran::runtime |