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