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