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