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