bid128_noncomp.c revision 1.1.1.1.4.2
1/* Copyright (C) 2007, 2009 Free Software Foundation, Inc. 2 3This file is part of GCC. 4 5GCC is free software; you can redistribute it and/or modify it under 6the terms of the GNU General Public License as published by the Free 7Software Foundation; either version 3, or (at your option) any later 8version. 9 10GCC is distributed in the hope that it will be useful, but WITHOUT ANY 11WARRANTY; without even the implied warranty of MERCHANTABILITY or 12FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13for more details. 14 15Under Section 7 of GPL version 3, you are granted additional 16permissions described in the GCC Runtime Library Exception, version 173.1, as published by the Free Software Foundation. 18 19You should have received a copy of the GNU General Public License and 20a copy of the GCC Runtime Library Exception along with this program; 21see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22<http://www.gnu.org/licenses/>. */ 23 24#include "bid_internal.h" 25 26/***************************************************************************** 27 * 28 * BID128 non-computational functions: 29 * - bid128_isSigned 30 * - bid128_isNormal 31 * - bid128_isSubnormal 32 * - bid128_isFinite 33 * - bid128_isZero 34 * - bid128_isInf 35 * - bid128_isSignaling 36 * - bid128_isCanonical 37 * - bid128_isNaN 38 * - bid128_copy 39 * - bid128_negate 40 * - bid128_abs 41 * - bid128_copySign 42 * - bid128_class 43 * - bid128_totalOrder 44 * - bid128_totalOrderMag 45 * - bid128_sameQuantum 46 * - bid128_radix 47 ****************************************************************************/ 48 49#if DECIMAL_CALL_BY_REFERENCE 50void 51bid128_isSigned (int *pres, 52 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 53 UINT128 x = *px; 54#else 55int 56bid128_isSigned (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 57#endif 58 int res; 59 60 res = ((x.w[HIGH_128W] & MASK_SIGN) == MASK_SIGN); 61 BID_RETURN (res); 62} 63 64// return 1 iff x is not zero, nor NaN nor subnormal nor infinity 65#if DECIMAL_CALL_BY_REFERENCE 66void 67bid128_isNormal (int *pres, 68 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 69 UINT128 x = *px; 70#else 71int 72bid128_isNormal (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 73#endif 74 int res; 75 UINT64 x_exp, C1_hi, C1_lo; 76 BID_UI64DOUBLE tmp1; 77 int exp, q, x_nr_bits; 78 79 BID_SWAP128 (x); 80 // test for special values - infinity or NaN 81 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 82 // x is special 83 res = 0; 84 BID_RETURN (res); 85 } 86 // unpack x 87 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 88 C1_hi = x.w[1] & MASK_COEFF; 89 C1_lo = x.w[0]; 90 // test for zero 91 if (C1_hi == 0 && C1_lo == 0) { 92 res = 0; 93 BID_RETURN (res); 94 } 95 // test for non-canonical values of the argument x 96 if ((((C1_hi > 0x0001ed09bead87c0ull) 97 || ((C1_hi == 0x0001ed09bead87c0ull) 98 && (C1_lo > 0x378d8e63ffffffffull))) 99 && ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) 100 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 101 res = 0; 102 BID_RETURN (res); 103 } 104 // x is subnormal or normal 105 // determine the number of digits q in the significand 106 // q = nr. of decimal digits in x 107 // determine first the nr. of bits in x 108 if (C1_hi == 0) { 109 if (C1_lo >= 0x0020000000000000ull) { // x >= 2^53 110 // split the 64-bit value in two 32-bit halves to avoid rounding errors 111 if (C1_lo >= 0x0000000100000000ull) { // x >= 2^32 112 tmp1.d = (double) (C1_lo >> 32); // exact conversion 113 x_nr_bits = 114 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 115 } else { // x < 2^32 116 tmp1.d = (double) (C1_lo); // exact conversion 117 x_nr_bits = 118 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 119 } 120 } else { // if x < 2^53 121 tmp1.d = (double) C1_lo; // exact conversion 122 x_nr_bits = 123 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 124 } 125 } else { // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi) 126 tmp1.d = (double) C1_hi; // exact conversion 127 x_nr_bits = 128 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 129 } 130 q = nr_digits[x_nr_bits - 1].digits; 131 if (q == 0) { 132 q = nr_digits[x_nr_bits - 1].digits1; 133 if (C1_hi > nr_digits[x_nr_bits - 1].threshold_hi || 134 (C1_hi == nr_digits[x_nr_bits - 1].threshold_hi && 135 C1_lo >= nr_digits[x_nr_bits - 1].threshold_lo)) 136 q++; 137 } 138 exp = (int) (x_exp >> 49) - 6176; 139 // test for subnormal values of x 140 if (exp + q <= -6143) { 141 res = 0; 142 BID_RETURN (res); 143 } else { 144 res = 1; 145 BID_RETURN (res); 146 } 147} 148 149// return 1 iff x is not zero, nor NaN nor normal nor infinity 150#if DECIMAL_CALL_BY_REFERENCE 151void 152bid128_isSubnormal (int *pres, 153 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 154 UINT128 x = *px; 155#else 156int 157bid128_isSubnormal (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 158#endif 159 int res; 160 UINT64 x_exp, C1_hi, C1_lo; 161 BID_UI64DOUBLE tmp1; 162 int exp, q, x_nr_bits; 163 164 BID_SWAP128 (x); 165 // test for special values - infinity or NaN 166 if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) { 167 // x is special 168 res = 0; 169 BID_RETURN (res); 170 } 171 // unpack x 172 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bit positions 173 C1_hi = x.w[1] & MASK_COEFF; 174 C1_lo = x.w[0]; 175 // test for zero 176 if (C1_hi == 0 && C1_lo == 0) { 177 res = 0; 178 BID_RETURN (res); 179 } 180 // test for non-canonical values of the argument x 181 if ((((C1_hi > 0x0001ed09bead87c0ull) 182 || ((C1_hi == 0x0001ed09bead87c0ull) 183 && (C1_lo > 0x378d8e63ffffffffull))) 184 && ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) 185 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 186 res = 0; 187 BID_RETURN (res); 188 } 189 // x is subnormal or normal 190 // determine the number of digits q in the significand 191 // q = nr. of decimal digits in x 192 // determine first the nr. of bits in x 193 if (C1_hi == 0) { 194 if (C1_lo >= 0x0020000000000000ull) { // x >= 2^53 195 // split the 64-bit value in two 32-bit halves to avoid rounding errors 196 if (C1_lo >= 0x0000000100000000ull) { // x >= 2^32 197 tmp1.d = (double) (C1_lo >> 32); // exact conversion 198 x_nr_bits = 199 33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 200 } else { // x < 2^32 201 tmp1.d = (double) (C1_lo); // exact conversion 202 x_nr_bits = 203 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 204 } 205 } else { // if x < 2^53 206 tmp1.d = (double) C1_lo; // exact conversion 207 x_nr_bits = 208 1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 209 } 210 } else { // C1_hi != 0 => nr. bits = 64 + nr_bits (C1_hi) 211 tmp1.d = (double) C1_hi; // exact conversion 212 x_nr_bits = 213 65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff); 214 } 215 q = nr_digits[x_nr_bits - 1].digits; 216 if (q == 0) { 217 q = nr_digits[x_nr_bits - 1].digits1; 218 if (C1_hi > nr_digits[x_nr_bits - 1].threshold_hi || 219 (C1_hi == nr_digits[x_nr_bits - 1].threshold_hi && 220 C1_lo >= nr_digits[x_nr_bits - 1].threshold_lo)) 221 q++; 222 } 223 exp = (int) (x_exp >> 49) - 6176; 224 // test for subnormal values of x 225 if (exp + q <= -6143) { 226 res = 1; 227 } else { 228 res = 0; 229 } 230 BID_RETURN (res); 231} 232 233#if DECIMAL_CALL_BY_REFERENCE 234void 235bid128_isFinite (int *pres, 236 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 237 UINT128 x = *px; 238#else 239int 240bid128_isFinite (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 241#endif 242 int res; 243 res = ((x.w[HIGH_128W] & MASK_INF) != MASK_INF); 244 BID_RETURN (res); 245} 246 247#if DECIMAL_CALL_BY_REFERENCE 248void 249bid128_isZero (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 250 UINT128 x = *px; 251#else 252int 253bid128_isZero (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 254#endif 255 int res; 256 UINT128 sig_x; 257 258 BID_SWAP128 (x); 259 if ((x.w[1] & MASK_INF) == MASK_INF) { 260 res = 0; 261 BID_RETURN (res); 262 } 263 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 264 sig_x.w[0] = x.w[0]; 265 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) || // significand is non-canonical 266 ((sig_x.w[1] == 0x0001ed09bead87c0ull) && (sig_x.w[0] > 0x378d8e63ffffffffull)) || // significand is non-canonical 267 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull && (x.w[1] & MASK_INF) != MASK_INF) || // significand is non-canonical 268 (sig_x.w[1] == 0 && sig_x.w[0] == 0)) { // significand is 0 269 res = 1; 270 BID_RETURN (res); 271 } 272 res = 0; 273 BID_RETURN (res); 274} 275 276#if DECIMAL_CALL_BY_REFERENCE 277void 278bid128_isInf (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 279 UINT128 x = *px; 280#else 281int 282bid128_isInf (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 283#endif 284 int res; 285 res = ((x.w[HIGH_128W] & MASK_INF) == MASK_INF) 286 && ((x.w[HIGH_128W] & MASK_NAN) != MASK_NAN); 287 BID_RETURN (res); 288} 289 290#if DECIMAL_CALL_BY_REFERENCE 291void 292bid128_isSignaling (int *pres, 293 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 294 UINT128 x = *px; 295#else 296int 297bid128_isSignaling (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 298#endif 299 int res; 300 301 res = ((x.w[HIGH_128W] & MASK_SNAN) == MASK_SNAN); 302 BID_RETURN (res); 303} 304 305// return 1 iff x is a canonical number ,infinity, or NaN. 306#if DECIMAL_CALL_BY_REFERENCE 307void 308bid128_isCanonical (int *pres, 309 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 310 UINT128 x = *px; 311#else 312int 313bid128_isCanonical (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 314#endif 315 int res; 316 UINT128 sig_x; 317 318 BID_SWAP128 (x); 319 if ((x.w[1] & MASK_NAN) == MASK_NAN) { // NaN 320 if (x.w[1] & 0x01ffc00000000000ull) { 321 res = 0; 322 BID_RETURN (res); 323 } 324 sig_x.w[1] = x.w[1] & 0x00003fffffffffffull; // 46 bits 325 sig_x.w[0] = x.w[0]; // 64 bits 326 // payload must be < 10^33 = 0x0000314dc6448d93_38c15b0a00000000 327 if (sig_x.w[1] < 0x0000314dc6448d93ull 328 || (sig_x.w[1] == 0x0000314dc6448d93ull 329 && sig_x.w[0] < 0x38c15b0a00000000ull)) { 330 res = 1; 331 } else { 332 res = 0; 333 } 334 BID_RETURN (res); 335 } else if ((x.w[1] & MASK_INF) == MASK_INF) { // infinity 336 if ((x.w[1] & 0x03ffffffffffffffull) || x.w[0]) { 337 res = 0; 338 } else { 339 res = 1; 340 } 341 BID_RETURN (res); 342 } 343 // not NaN or infinity; extract significand to ensure it is canonical 344 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 345 sig_x.w[0] = x.w[0]; 346 // a canonical number has a coefficient < 10^34 347 // (0x0001ed09_bead87c0_378d8e64_00000000) 348 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) || // significand is non-canonical 349 ((sig_x.w[1] == 0x0001ed09bead87c0ull) && (sig_x.w[0] > 0x378d8e63ffffffffull)) || // significand is non-canonical 350 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) { 351 res = 0; 352 } else { 353 res = 1; 354 } 355 BID_RETURN (res); 356} 357 358#if DECIMAL_CALL_BY_REFERENCE 359void 360bid128_isNaN (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 361 UINT128 x = *px; 362#else 363int 364bid128_isNaN (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 365#endif 366 int res; 367 368 res = ((x.w[HIGH_128W] & MASK_NAN) == MASK_NAN); 369 BID_RETURN (res); 370} 371 372// copies a floating-point operand x to destination y, with no change 373#if DECIMAL_CALL_BY_REFERENCE 374void 375bid128_copy (UINT128 * pres, 376 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 377 UINT128 x = *px; 378#else 379UINT128 380bid128_copy (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 381#endif 382 UINT128 res; 383 384 res = x; 385 BID_RETURN (res); 386} 387 388// copies a floating-point operand x to destination y, reversing the sign 389#if DECIMAL_CALL_BY_REFERENCE 390void 391bid128_negate (UINT128 * pres, 392 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 393 UINT128 x = *px; 394#else 395UINT128 396bid128_negate (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 397#endif 398 UINT128 res; 399 400 x.w[HIGH_128W] ^= MASK_SIGN; 401 res = x; 402 BID_RETURN (res); 403} 404 405// copies a floating-point operand x to destination y, changing the sign to positive 406#if DECIMAL_CALL_BY_REFERENCE 407void 408bid128_abs (UINT128 * pres, 409 UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 410 UINT128 x = *px; 411#else 412UINT128 413bid128_abs (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 414#endif 415 UINT128 res; 416 417 x.w[HIGH_128W] &= ~MASK_SIGN; 418 res = x; 419 BID_RETURN (res); 420} 421 422// copies operand x to destination in the same format as x, but with the sign of y 423#if DECIMAL_CALL_BY_REFERENCE 424void 425bid128_copySign (UINT128 * pres, UINT128 * px, 426 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 427 UINT128 x = *px; 428 UINT128 y = *py; 429#else 430UINT128 431bid128_copySign (UINT128 x, UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 432#endif 433 UINT128 res; 434 435 x.w[HIGH_128W] = 436 (x.w[HIGH_128W] & ~MASK_SIGN) | (y.w[HIGH_128W] & MASK_SIGN); 437 res = x; 438 BID_RETURN (res); 439} 440 441#if DECIMAL_CALL_BY_REFERENCE 442void 443bid128_class (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 444 UINT128 x = *px; 445#else 446int 447bid128_class (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 448#endif 449 int res; 450 UINT256 sig_x_prime256; 451 UINT192 sig_x_prime192; 452 UINT128 sig_x; 453 int exp_x; 454 455 BID_SWAP128 (x); 456 if ((x.w[1] & MASK_NAN) == MASK_NAN) { 457 if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { 458 res = signalingNaN; 459 } else { 460 res = quietNaN; 461 } 462 BID_RETURN (res); 463 } 464 if ((x.w[1] & MASK_INF) == MASK_INF) { 465 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) { 466 res = negativeInfinity; 467 } else { 468 res = positiveInfinity; 469 } 470 BID_RETURN (res); 471 } 472 // decode number into exponent and significand 473 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 474 sig_x.w[0] = x.w[0]; 475 // check for zero or non-canonical 476 if ((sig_x.w[1] > 0x0001ed09bead87c0ull) 477 || ((sig_x.w[1] == 0x0001ed09bead87c0ull) 478 && (sig_x.w[0] > 0x378d8e63ffffffffull)) 479 || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) 480 || ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 481 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) { 482 res = negativeZero; 483 } else { 484 res = positiveZero; 485 } 486 BID_RETURN (res); 487 } 488 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 489 // if exponent is less than -6176, the number may be subnormal 490 // (less than the smallest normal value) 491 // the smallest normal value is 1 x 10^-6143 = 10^33 x 10^-6176 492 // if (exp_x - 6176 < -6143) 493 if (exp_x < 33) { // sig_x * 10^exp_x 494 if (exp_x > 19) { 495 __mul_128x128_to_256 (sig_x_prime256, sig_x, 496 ten2k128[exp_x - 20]); 497 // 10^33 = 0x0000314dc6448d93_38c15b0a00000000 498 if ((sig_x_prime256.w[3] == 0) && (sig_x_prime256.w[2] == 0) 499 && ((sig_x_prime256.w[1] < 0x0000314dc6448d93ull) 500 || ((sig_x_prime256.w[1] == 0x0000314dc6448d93ull) 501 && (sig_x_prime256.w[0] < 0x38c15b0a00000000ull)))) { 502 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? negativeSubnormal : 503 positiveSubnormal; 504 BID_RETURN (res); 505 } 506 } else { 507 __mul_64x128_to_192 (sig_x_prime192, ten2k64[exp_x], sig_x); 508 // 10^33 = 0x0000314dc6448d93_38c15b0a00000000 509 if ((sig_x_prime192.w[2] == 0) 510 && ((sig_x_prime192.w[1] < 0x0000314dc6448d93ull) 511 || ((sig_x_prime192.w[1] == 0x0000314dc6448d93ull) 512 && (sig_x_prime192.w[0] < 0x38c15b0a00000000ull)))) { 513 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN) ? negativeSubnormal : 514 positiveSubnormal; 515 BID_RETURN (res); 516 } 517 } 518 } 519 // otherwise, normal number, determine the sign 520 res = 521 ((x.w[1] & MASK_SIGN) == 522 MASK_SIGN) ? negativeNormal : positiveNormal; 523 BID_RETURN (res); 524} 525 526// true if the exponents of x and y are the same, false otherwise. 527// The special cases of sameQuantum(NaN, NaN) and sameQuantum(Inf, Inf) are true 528// If exactly one operand is infinite or exactly one operand is NaN, then false 529#if DECIMAL_CALL_BY_REFERENCE 530void 531bid128_sameQuantum (int *pres, UINT128 * px, 532 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 533 UINT128 x = *px; 534 UINT128 y = *py; 535#else 536int 537bid128_sameQuantum (UINT128 x, 538 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 539#endif 540 int res; 541 UINT64 x_exp, y_exp; 542 543 BID_SWAP128 (x); 544 BID_SWAP128 (y); 545 // if both operands are NaN, return true 546 if ((x.w[1] & MASK_NAN) == MASK_NAN 547 || ((y.w[1] & MASK_NAN) == MASK_NAN)) { 548 res = ((x.w[1] & MASK_NAN) == MASK_NAN 549 && (y.w[1] & MASK_NAN) == MASK_NAN); 550 BID_RETURN (res); 551 } 552 // if both operands are INF, return true 553 if ((x.w[1] & MASK_INF) == MASK_INF 554 || (y.w[1] & MASK_INF) == MASK_INF) { 555 res = ((x.w[1] & MASK_INF) == MASK_INF) 556 && ((y.w[1] & MASK_INF) == MASK_INF); 557 BID_RETURN (res); 558 } 559 // decode exponents for both numbers, and return true if they match 560 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11 561 x_exp = (x.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits 562 } else { // G0_G1 != 11 563 x_exp = x.w[1] & MASK_EXP; // biased and shifted left 49 bits 564 } 565 if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { // G0_G1=11 566 y_exp = (y.w[1] << 2) & MASK_EXP; // biased and shifted left 49 bits 567 } else { // G0_G1 != 11 568 y_exp = y.w[1] & MASK_EXP; // biased and shifted left 49 bits 569 } 570 res = (x_exp == y_exp); 571 BID_RETURN (res); 572} 573 574#if DECIMAL_CALL_BY_REFERENCE 575void 576bid128_totalOrder (int *pres, UINT128 * px, 577 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 578 UINT128 x = *px; 579 UINT128 y = *py; 580#else 581int 582bid128_totalOrder (UINT128 x, 583 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 584#endif 585 int res; 586 int exp_x, exp_y; 587 UINT128 sig_x, sig_y, pyld_y, pyld_x; 588 UINT192 sig_n_prime192; 589 UINT256 sig_n_prime256; 590 char x_is_zero = 0, y_is_zero = 0; 591 592 BID_SWAP128 (x); 593 BID_SWAP128 (y); 594 // NaN (CASE 1) 595 // if x and y are unordered numerically because either operand is NaN 596 // (1) totalOrder(-NaN, number) is true 597 // (2) totalOrder(number, +NaN) is true 598 // (3) if x and y are both NaN: 599 // i) negative sign bit < positive sign bit 600 // ii) signaling < quiet for +NaN, reverse for -NaN 601 // iii) lesser payload < greater payload for +NaN (reverse for -NaN) 602 // iv) else if bitwise identical (in canonical form), return 1 603 if ((x.w[1] & MASK_NAN) == MASK_NAN) { 604 // if x is -NaN 605 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) { 606 // return true, unless y is -NaN also 607 if ((y.w[1] & MASK_NAN) != MASK_NAN 608 || (y.w[1] & MASK_SIGN) != MASK_SIGN) { 609 res = 1; // y is a number, return 1 610 BID_RETURN (res); 611 } else { // if y and x are both -NaN 612 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull; 613 pyld_x.w[0] = x.w[0]; 614 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull; 615 pyld_y.w[0] = y.w[0]; 616 if ((pyld_x.w[1] > 0x0000314dc6448d93ull) 617 || ((pyld_x.w[1] == 0x0000314dc6448d93ull) 618 && (pyld_x.w[0] > 0x38c15b09ffffffffull))) { 619 pyld_x.w[1] = 0; 620 pyld_x.w[0] = 0; 621 } 622 if ((pyld_y.w[1] > 0x0000314dc6448d93ull) 623 || ((pyld_y.w[1] == 0x0000314dc6448d93ull) 624 && (pyld_y.w[0] > 0x38c15b09ffffffffull))) { 625 pyld_y.w[1] = 0; 626 pyld_y.w[0] = 0; 627 } 628 // if x and y are both -SNaN or both -QNaN, we have to compare payloads 629 // this statement evaluates to true if both are SNaN or QNaN 630 if (! 631 (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^ 632 ((x.w[1] & MASK_SNAN) == MASK_SNAN))) { 633 // it comes down to the payload. we want to return true if x has a 634 // larger payload, or if the payloads are equal (canonical forms 635 // are bitwise identical) 636 if ((pyld_x.w[1] > pyld_y.w[1]) || 637 ((pyld_x.w[1] == pyld_y.w[1]) 638 && (pyld_x.w[0] >= pyld_y.w[0]))) 639 res = 1; 640 else 641 res = 0; 642 BID_RETURN (res); 643 } else { 644 // either x = -SNaN and y = -QNaN or x = -QNaN and y = -SNaN 645 res = ((y.w[1] & MASK_SNAN) == MASK_SNAN); 646 // totalOrder (-QNaN, -SNaN) == 1 647 BID_RETURN (res); 648 } 649 } 650 } else { // x is +NaN 651 // return false, unless y is +NaN also 652 if ((y.w[1] & MASK_NAN) != MASK_NAN 653 || (y.w[1] & MASK_SIGN) == MASK_SIGN) { 654 res = 0; // y is a number, return 1 655 BID_RETURN (res); 656 } else { 657 // x and y are both +NaN; 658 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull; 659 pyld_x.w[0] = x.w[0]; 660 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull; 661 pyld_y.w[0] = y.w[0]; 662 if ((pyld_x.w[1] > 0x0000314dc6448d93ull) 663 || ((pyld_x.w[1] == 0x0000314dc6448d93ull) 664 && (pyld_x.w[0] > 0x38c15b09ffffffffull))) { 665 pyld_x.w[1] = 0; 666 pyld_x.w[0] = 0; 667 } 668 if ((pyld_y.w[1] > 0x0000314dc6448d93ull) 669 || ((pyld_y.w[1] == 0x0000314dc6448d93ull) 670 && (pyld_y.w[0] > 0x38c15b09ffffffffull))) { 671 pyld_y.w[1] = 0; 672 pyld_y.w[0] = 0; 673 } 674 // if x and y are both +SNaN or both +QNaN, we have to compare payloads 675 // this statement evaluates to true if both are SNaN or QNaN 676 if (! 677 (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^ 678 ((x.w[1] & MASK_SNAN) == MASK_SNAN))) { 679 // it comes down to the payload. we want to return true if x has a 680 // smaller payload, or if the payloads are equal (canonical forms 681 // are bitwise identical) 682 if ((pyld_x.w[1] < pyld_y.w[1]) || 683 ((pyld_x.w[1] == pyld_y.w[1]) 684 && (pyld_x.w[0] <= pyld_y.w[0]))) 685 res = 1; 686 else 687 res = 0; 688 BID_RETURN (res); 689 } else { 690 // either x = SNaN and y = QNaN or x = QNaN and y = SNaN 691 res = ((x.w[1] & MASK_SNAN) == MASK_SNAN); 692 // totalOrder (-QNaN, -SNaN) == 1 693 BID_RETURN (res); 694 } 695 } 696 } 697 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { 698 // x is certainly not NAN in this case. 699 // return true if y is positive 700 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 701 BID_RETURN (res); 702 } 703 // SIMPLE (CASE 2) 704 // if all the bits are the same, the numbers are equal. 705 if ((x.w[1] == y.w[1]) && (x.w[0] == y.w[0])) { 706 res = 1; 707 BID_RETURN (res); 708 } 709 // OPPOSITE SIGNS (CASE 3) 710 // if signs are opposite, return 1 if x is negative 711 // (if x < y, totalOrder is true) 712 if (((x.w[1] & MASK_SIGN) == MASK_SIGN) ^ ((y.w[1] & MASK_SIGN) == 713 MASK_SIGN)) { 714 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 715 BID_RETURN (res); 716 } 717 // INFINITY (CASE 4) 718 if ((x.w[1] & MASK_INF) == MASK_INF) { 719 // if x == neg_inf, return (y == neg_inf); 720 if ((x.w[1] & MASK_SIGN) == MASK_SIGN) { 721 res = 1; 722 BID_RETURN (res); 723 } else { 724 // x is positive infinity, only return1 if y is positive infinity as well 725 res = ((y.w[1] & MASK_INF) == MASK_INF); 726 BID_RETURN (res); 727 // && (y & MASK_SIGN) != MASK_SIGN); (we know y has same sign as x) 728 } 729 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 730 // x is finite, so: 731 // if y is +inf, x<y 732 // if y is -inf, x>y 733 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 734 BID_RETURN (res); 735 } 736 // CONVERT x 737 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 738 sig_x.w[0] = x.w[0]; 739 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 740 741 // CHECK IF x IS CANONICAL 742 // 9999999999999999999999999999999999 (decimal) = 743 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 744 // [0, 10^34) is the 754r supported canonical range. 745 // If the value exceeds that, it is interpreted as 0. 746 if ((((sig_x.w[1] > 0x0001ed09bead87c0ull) || 747 ((sig_x.w[1] == 0x0001ed09bead87c0ull) && 748 (sig_x.w[0] > 0x378d8e63ffffffffull))) && 749 ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) || 750 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) || 751 ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 752 x_is_zero = 1; 753 // check for the case where the exponent is shifted right by 2 bits! 754 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { 755 exp_x = (x.w[1] >> 47) & 0x000000000003fffull; 756 } 757 } 758 // CONVERT y 759 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 760 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 761 sig_y.w[0] = y.w[0]; 762 763 // CHECK IF y IS CANONICAL 764 // 9999999999999999999999999999999999(decimal) = 765 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 766 // [0, 10^34) is the 754r supported canonical range. 767 // If the value exceeds that, it is interpreted as 0. 768 if ((((sig_y.w[1] > 0x0001ed09bead87c0ull) || 769 ((sig_y.w[1] == 0x0001ed09bead87c0ull) && 770 (sig_y.w[0] > 0x378d8e63ffffffffull))) && 771 ((y.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) || 772 ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) || 773 ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 774 y_is_zero = 1; 775 // check for the case where the exponent is shifted right by 2 bits! 776 if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { 777 exp_y = (y.w[1] >> 47) & 0x000000000003fffull; 778 } 779 } 780 // ZERO (CASE 5) 781 // if x and y represent the same entities, and both are negative 782 // return true iff exp_x <= exp_y 783 if (x_is_zero && y_is_zero) { 784 // we know that signs must be the same because we would have caught it 785 // in case3 if signs were different 786 // totalOrder(x,y) iff exp_x >= exp_y for negative numbers 787 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers 788 if (exp_x == exp_y) { 789 res = 1; 790 BID_RETURN (res); 791 } 792 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 793 BID_RETURN (res); 794 } 795 // if x is zero and y isn't, clearly x has the smaller payload 796 if (x_is_zero) { 797 res = ((y.w[1] & MASK_SIGN) != MASK_SIGN); 798 BID_RETURN (res); 799 } 800 // if y is zero, and x isn't, clearly y has the smaller payload 801 if (y_is_zero) { 802 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 803 BID_RETURN (res); 804 } 805 // REDUNDANT REPRESENTATIONS (CASE 6) 806 // if both components are either bigger or smaller 807 if (((sig_x.w[1] > sig_y.w[1]) 808 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 809 && exp_x >= exp_y) { 810 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 811 BID_RETURN (res); 812 } 813 if (((sig_x.w[1] < sig_y.w[1]) 814 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 815 && exp_x <= exp_y) { 816 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 817 BID_RETURN (res); 818 } 819 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 820 if (exp_x > exp_y) { 821 // if exp_x is 33 greater than exp_y, it is definitely larger, 822 // so no need for compensation 823 if (exp_x - exp_y > 33) { 824 res = ((x.w[1] & MASK_SIGN) == MASK_SIGN); 825 BID_RETURN (res); 826 // difference cannot be greater than 10^33 827 } 828 // otherwise adjust the x significand upwards 829 if (exp_x - exp_y > 19) { 830 __mul_128x128_to_256 (sig_n_prime256, sig_x, 831 ten2k128[exp_x - exp_y - 20]); 832 // the compensated significands are equal (ie "x and y represent the same 833 // entities") return 1 if (negative && expx > expy) || 834 // (positive && expx < expy) 835 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0) 836 && (sig_n_prime256.w[1] == sig_y.w[1]) 837 && (sig_n_prime256.w[0] == sig_y.w[0])) { 838 // the case exp_x == exp_y cannot occur, because all bits must be 839 // the same - would have been caught if (x == y) 840 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 841 BID_RETURN (res); 842 } 843 // if positive, return 1 if adjusted x is smaller than y 844 res = (((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0) 845 && ((sig_n_prime256.w[1] < sig_y.w[1]) 846 || (sig_n_prime256.w[1] == sig_y.w[1] 847 && sig_n_prime256.w[0] < 848 sig_y.w[0]))) ^ ((x.w[1] & MASK_SIGN) == 849 MASK_SIGN)); 850 BID_RETURN (res); 851 } 852 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_x - exp_y], sig_x); 853 // if positive, return whichever significand is larger 854 // (converse if negative) 855 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 856 && (sig_n_prime192.w[0] == sig_y.w[0])) { 857 res = ((exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 858 BID_RETURN (res); 859 } 860 res = (((sig_n_prime192.w[2] == 0) 861 && ((sig_n_prime192.w[1] < sig_y.w[1]) 862 || (sig_n_prime192.w[1] == sig_y.w[1] 863 && sig_n_prime192.w[0] < 864 sig_y.w[0]))) ^ ((x.w[1] & MASK_SIGN) == 865 MASK_SIGN)); 866 BID_RETURN (res); 867 } 868 // if exp_x is 33 less than exp_y, it is definitely smaller, 869 // no need for compensation 870 if (exp_y - exp_x > 33) { 871 res = ((x.w[1] & MASK_SIGN) != MASK_SIGN); 872 BID_RETURN (res); 873 } 874 if (exp_y - exp_x > 19) { 875 // adjust the y significand upwards 876 __mul_128x128_to_256 (sig_n_prime256, sig_y, 877 ten2k128[exp_y - exp_x - 20]); 878 // if x and y represent the same entities and both are negative 879 // return true iff exp_x <= exp_y 880 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0) 881 && (sig_n_prime256.w[1] == sig_x.w[1]) 882 && (sig_n_prime256.w[0] == sig_x.w[0])) { 883 res = (exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN); 884 BID_RETURN (res); 885 } 886 // values are not equal, for positive numbers return 1 if x is less than y 887 // and 0 otherwise 888 res = (((sig_n_prime256.w[3] != 0) || 889 // if upper128 bits of compensated y are non-zero, y is bigger 890 (sig_n_prime256.w[2] != 0) || 891 // if upper128 bits of compensated y are non-zero, y is bigger 892 (sig_n_prime256.w[1] > sig_x.w[1]) || 893 // if compensated y is bigger, y is bigger 894 (sig_n_prime256.w[1] == sig_x.w[1] 895 && sig_n_prime256.w[0] > 896 sig_x.w[0])) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 897 BID_RETURN (res); 898 } 899 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y); 900 if ((sig_n_prime192.w[2] == 0) && (sig_n_prime192.w[1] == sig_x.w[1]) 901 && (sig_n_prime192.w[0] == sig_x.w[0])) { 902 res = (exp_x <= exp_y) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN); 903 BID_RETURN (res); 904 } 905 res = (((sig_n_prime192.w[2] != 0) || 906 // if upper128 bits of compensated y are non-zero, y is bigger 907 (sig_n_prime192.w[1] > sig_x.w[1]) || 908 // if compensated y is bigger, y is bigger 909 (sig_n_prime192.w[1] == sig_x.w[1] 910 && sig_n_prime192.w[0] > 911 sig_x.w[0])) ^ ((x.w[1] & MASK_SIGN) == MASK_SIGN)); 912 BID_RETURN (res); 913} 914 915#if DECIMAL_CALL_BY_REFERENCE 916void 917bid128_totalOrderMag (int *pres, UINT128 * px, 918 UINT128 * py _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 919 UINT128 x = *px; 920 UINT128 y = *py; 921#else 922int 923bid128_totalOrderMag (UINT128 x, 924 UINT128 y _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 925#endif 926 int res; 927 int exp_x, exp_y; 928 UINT128 sig_x, sig_y, pyld_y, pyld_x; 929 UINT192 sig_n_prime192; 930 UINT256 sig_n_prime256; 931 char x_is_zero = 0, y_is_zero = 0; 932 933 BID_SWAP128 (x); 934 BID_SWAP128 (y); 935 x.w[1] = x.w[1] & 0x7fffffffffffffffull; 936 y.w[1] = y.w[1] & 0x7fffffffffffffffull; 937 938 // NaN (CASE 1) 939 // if x and y are unordered numerically because either operand is NaN 940 // (1) totalOrder(number, +NaN) is true 941 // (2) if x and y are both NaN: 942 // i) signaling < quiet for +NaN 943 // ii) lesser payload < greater payload for +NaN 944 // iii) else if bitwise identical (in canonical form), return 1 945 if ((x.w[1] & MASK_NAN) == MASK_NAN) { 946 // x is +NaN 947 // return false, unless y is +NaN also 948 if ((y.w[1] & MASK_NAN) != MASK_NAN) { 949 res = 0; // y is a number, return 0 950 BID_RETURN (res); 951 } else { 952 // x and y are both +NaN; 953 pyld_x.w[1] = x.w[1] & 0x00003fffffffffffull; 954 pyld_x.w[0] = x.w[0]; 955 pyld_y.w[1] = y.w[1] & 0x00003fffffffffffull; 956 pyld_y.w[0] = y.w[0]; 957 if ((pyld_x.w[1] > 0x0000314dc6448d93ull) 958 || ((pyld_x.w[1] == 0x0000314dc6448d93ull) 959 && (pyld_x.w[0] > 0x38c15b09ffffffffull))) { 960 pyld_x.w[1] = 0; 961 pyld_x.w[0] = 0; 962 } 963 if ((pyld_y.w[1] > 0x0000314dc6448d93ull) 964 || ((pyld_y.w[1] == 0x0000314dc6448d93ull) 965 && (pyld_y.w[0] > 0x38c15b09ffffffffull))) { 966 pyld_y.w[1] = 0; 967 pyld_y.w[0] = 0; 968 } 969 // if x and y are both +SNaN or both +QNaN, we have to compare payloads 970 // this statement evaluates to true if both are SNaN or QNaN 971 if (! 972 (((y.w[1] & MASK_SNAN) == MASK_SNAN) ^ 973 ((x.w[1] & MASK_SNAN) == MASK_SNAN))) { 974 // it comes down to the payload. we want to return true if x has a 975 // smaller payload, or if the payloads are equal (canonical forms 976 // are bitwise identical) 977 if ((pyld_x.w[1] < pyld_y.w[1]) || 978 ((pyld_x.w[1] == pyld_y.w[1]) 979 && (pyld_x.w[0] <= pyld_y.w[0]))) { 980 res = 1; 981 } else { 982 res = 0; 983 } 984 BID_RETURN (res); 985 } else { 986 // either x = SNaN and y = QNaN or x = QNaN and y = SNaN 987 res = ((x.w[1] & MASK_SNAN) == MASK_SNAN); 988 // totalOrder (-QNaN, -SNaN) == 1 989 BID_RETURN (res); 990 } 991 } 992 } else if ((y.w[1] & MASK_NAN) == MASK_NAN) { 993 // x is certainly not NAN in this case. 994 // return true because y is positive 995 res = 1; 996 BID_RETURN (res); 997 } 998 // SIMPLE (CASE 2) 999 // if all the bits are the same, the numbers are equal. 1000 if ((x.w[1] == y.w[1]) && (x.w[0] == y.w[0])) { 1001 res = 1; 1002 BID_RETURN (res); 1003 } 1004 // INFINITY (CASE 3) 1005 if ((x.w[1] & MASK_INF) == MASK_INF) { 1006 // x is positive infinity, only return 1 if y is positive infinity as well 1007 res = ((y.w[1] & MASK_INF) == MASK_INF); 1008 BID_RETURN (res); 1009 // (we know y has same sign as x) 1010 } else if ((y.w[1] & MASK_INF) == MASK_INF) { 1011 // x is finite, so: 1012 // since y is +inf, x<y 1013 res = 1; 1014 BID_RETURN (res); 1015 } else { 1016 ; // continue 1017 } 1018 1019 // CONVERT x 1020 sig_x.w[1] = x.w[1] & 0x0001ffffffffffffull; 1021 sig_x.w[0] = x.w[0]; 1022 exp_x = (x.w[1] >> 49) & 0x000000000003fffull; 1023 1024 // CHECK IF x IS CANONICAL 1025 // 9999999999999999999999999999999999 (decimal) = 1026 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1027 // [0, 10^34) is the 754r supported canonical range. 1028 // If the value exceeds that, it is interpreted as 0. 1029 if ((((sig_x.w[1] > 0x0001ed09bead87c0ull) || 1030 ((sig_x.w[1] == 0x0001ed09bead87c0ull) && 1031 (sig_x.w[0] > 0x378d8e63ffffffffull))) && 1032 ((x.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) || 1033 ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) || 1034 ((sig_x.w[1] == 0) && (sig_x.w[0] == 0))) { 1035 x_is_zero = 1; 1036 // check for the case where the exponent is shifted right by 2 bits! 1037 if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { 1038 exp_x = (x.w[1] >> 47) & 0x000000000003fffull; 1039 } 1040 } 1041 // CONVERT y 1042 exp_y = (y.w[1] >> 49) & 0x0000000000003fffull; 1043 sig_y.w[1] = y.w[1] & 0x0001ffffffffffffull; 1044 sig_y.w[0] = y.w[0]; 1045 1046 // CHECK IF y IS CANONICAL 1047 // 9999999999999999999999999999999999(decimal) = 1048 // 1ed09_bead87c0_378d8e63_ffffffff(hexadecimal) 1049 // [0, 10^34) is the 754r supported canonical range. 1050 // If the value exceeds that, it is interpreted as 0. 1051 if ((((sig_y.w[1] > 0x0001ed09bead87c0ull) || 1052 ((sig_y.w[1] == 0x0001ed09bead87c0ull) && 1053 (sig_y.w[0] > 0x378d8e63ffffffffull))) && 1054 ((y.w[1] & 0x6000000000000000ull) != 0x6000000000000000ull)) || 1055 ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) || 1056 ((sig_y.w[1] == 0) && (sig_y.w[0] == 0))) { 1057 y_is_zero = 1; 1058 // check for the case where the exponent is shifted right by 2 bits! 1059 if ((y.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) { 1060 exp_y = (y.w[1] >> 47) & 0x000000000003fffull; 1061 } 1062 } 1063 // ZERO (CASE 4) 1064 if (x_is_zero && y_is_zero) { 1065 // we know that signs must be the same because we would have caught it 1066 // in case3 if signs were different 1067 // totalOrder(x,y) iff exp_x <= exp_y for positive numbers 1068 if (exp_x == exp_y) { 1069 res = 1; 1070 BID_RETURN (res); 1071 } 1072 res = (exp_x <= exp_y); 1073 BID_RETURN (res); 1074 } 1075 // if x is zero and y isn't, clearly x has the smaller payload 1076 if (x_is_zero) { 1077 res = 1; 1078 BID_RETURN (res); 1079 } 1080 // if y is zero, and x isn't, clearly y has the smaller payload 1081 if (y_is_zero) { 1082 res = 0; 1083 BID_RETURN (res); 1084 } 1085 // REDUNDANT REPRESENTATIONS (CASE 5) 1086 // if both components are either bigger or smaller 1087 if (((sig_x.w[1] > sig_y.w[1]) 1088 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] > sig_y.w[0])) 1089 && exp_x >= exp_y) { 1090 res = 0; 1091 BID_RETURN (res); 1092 } 1093 if (((sig_x.w[1] < sig_y.w[1]) 1094 || (sig_x.w[1] == sig_y.w[1] && sig_x.w[0] < sig_y.w[0])) 1095 && exp_x <= exp_y) { 1096 res = 1; 1097 BID_RETURN (res); 1098 } 1099 // if |exp_x - exp_y| < 33, it comes down to the compensated significand 1100 if (exp_x > exp_y) { 1101 // if exp_x is 33 greater than exp_y, it is definitely larger, 1102 // so no need for compensation 1103 if (exp_x - exp_y > 33) { 1104 res = 0; // difference cannot be greater than 10^33 1105 BID_RETURN (res); 1106 } 1107 // otherwise adjust the x significand upwards 1108 if (exp_x - exp_y > 19) { 1109 __mul_128x128_to_256 (sig_n_prime256, sig_x, 1110 ten2k128[exp_x - exp_y - 20]); 1111 // the compensated significands are equal (ie "x and y represent the same 1112 // entities") return 1 if (negative && expx > expy) || 1113 // (positive && expx < expy) 1114 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0) 1115 && (sig_n_prime256.w[1] == sig_y.w[1]) 1116 && (sig_n_prime256.w[0] == sig_y.w[0])) { 1117 // the case (exp_x == exp_y) cannot occur, because all bits must be 1118 // the same - would have been caught if (x == y) 1119 res = (exp_x <= exp_y); 1120 BID_RETURN (res); 1121 } 1122 // since positive, return 1 if adjusted x is smaller than y 1123 res = ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0) 1124 && ((sig_n_prime256.w[1] < sig_y.w[1]) 1125 || (sig_n_prime256.w[1] == sig_y.w[1] 1126 && sig_n_prime256.w[0] < sig_y.w[0]))); 1127 BID_RETURN (res); 1128 } 1129 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_x - exp_y], sig_x); 1130 // if positive, return whichever significand is larger 1131 // (converse if negative) 1132 if ((sig_n_prime192.w[2] == 0) && sig_n_prime192.w[1] == sig_y.w[1] 1133 && (sig_n_prime192.w[0] == sig_y.w[0])) { 1134 res = (exp_x <= exp_y); 1135 BID_RETURN (res); 1136 } 1137 res = ((sig_n_prime192.w[2] == 0) 1138 && ((sig_n_prime192.w[1] < sig_y.w[1]) 1139 || (sig_n_prime192.w[1] == sig_y.w[1] 1140 && sig_n_prime192.w[0] < sig_y.w[0]))); 1141 BID_RETURN (res); 1142 } 1143 // if exp_x is 33 less than exp_y, it is definitely smaller, 1144 // no need for compensation 1145 if (exp_y - exp_x > 33) { 1146 res = 1; 1147 BID_RETURN (res); 1148 } 1149 if (exp_y - exp_x > 19) { 1150 // adjust the y significand upwards 1151 __mul_128x128_to_256 (sig_n_prime256, sig_y, 1152 ten2k128[exp_y - exp_x - 20]); 1153 if ((sig_n_prime256.w[3] == 0) && (sig_n_prime256.w[2] == 0) 1154 && (sig_n_prime256.w[1] == sig_x.w[1]) 1155 && (sig_n_prime256.w[0] == sig_x.w[0])) { 1156 res = (exp_x <= exp_y); 1157 BID_RETURN (res); 1158 } 1159 // values are not equal, for positive numbers return 1 if x is less than y 1160 // and 0 otherwise 1161 res = ((sig_n_prime256.w[3] != 0) || 1162 // if upper128 bits of compensated y are non-zero, y is bigger 1163 (sig_n_prime256.w[2] != 0) || 1164 // if upper128 bits of compensated y are non-zero, y is bigger 1165 (sig_n_prime256.w[1] > sig_x.w[1]) || 1166 // if compensated y is bigger, y is bigger 1167 (sig_n_prime256.w[1] == sig_x.w[1] 1168 && sig_n_prime256.w[0] > sig_x.w[0])); 1169 BID_RETURN (res); 1170 } 1171 __mul_64x128_to_192 (sig_n_prime192, ten2k64[exp_y - exp_x], sig_y); 1172 if ((sig_n_prime192.w[2] == 0) && (sig_n_prime192.w[1] == sig_x.w[1]) 1173 && (sig_n_prime192.w[0] == sig_x.w[0])) { 1174 res = (exp_x <= exp_y); 1175 BID_RETURN (res); 1176 } 1177 res = ((sig_n_prime192.w[2] != 0) || 1178 // if upper128 bits of compensated y are non-zero, y is bigger 1179 (sig_n_prime192.w[1] > sig_x.w[1]) || 1180 // if compensated y is bigger, y is bigger 1181 (sig_n_prime192.w[1] == sig_x.w[1] 1182 && sig_n_prime192.w[0] > sig_x.w[0])); 1183 BID_RETURN (res); 1184} 1185 1186#if DECIMAL_CALL_BY_REFERENCE 1187void 1188bid128_radix (int *pres, UINT128 * px _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 1189 UINT128 x = *px; 1190#else 1191int 1192bid128_radix (UINT128 x _EXC_MASKS_PARAM _EXC_INFO_PARAM) { 1193#endif 1194 int res; 1195 if (x.w[LOW_128W]) // dummy test 1196 res = 10; 1197 else 1198 res = 10; 1199 BID_RETURN (res); 1200} 1201