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