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