1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include <string.h> 19 #include "cbigint.h" 20 21 #if defined(__linux__) || defined(FREEBSD) || defined(ZOS) || defined(MACOSX) || defined(AIX) 22 #define USE_LL 23 #endif 24 25 #if __BYTE_ORDER == __LITTLE_ENDIAN 26 #define at(i) (i) 27 #else 28 #define at(i) ((i)^1) 29 /* the sequence for halfAt is -1, 2, 1, 4, 3, 6, 5, 8... */ 30 /* and it should correspond to 0, 1, 2, 3, 4, 5, 6, 7... */ 31 #define halfAt(i) (-((-(i)) ^ 1)) 32 #endif 33 34 #define HIGH_IN_U64(u64) ((u64) >> 32) 35 #if defined(USE_LL) 36 #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFLL) 37 #else 38 #if defined(USE_L) 39 #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFFL) 40 #else 41 #define LOW_IN_U64(u64) ((u64) & 0x00000000FFFFFFFF) 42 #endif /* USE_L */ 43 #endif /* USE_LL */ 44 45 #if defined(USE_LL) 46 #define TEN_E1 (0xALL) 47 #define TEN_E2 (0x64LL) 48 #define TEN_E3 (0x3E8LL) 49 #define TEN_E4 (0x2710LL) 50 #define TEN_E5 (0x186A0LL) 51 #define TEN_E6 (0xF4240LL) 52 #define TEN_E7 (0x989680LL) 53 #define TEN_E8 (0x5F5E100LL) 54 #define TEN_E9 (0x3B9ACA00LL) 55 #define TEN_E19 (0x8AC7230489E80000LL) 56 #else 57 #if defined(USE_L) 58 #define TEN_E1 (0xAL) 59 #define TEN_E2 (0x64L) 60 #define TEN_E3 (0x3E8L) 61 #define TEN_E4 (0x2710L) 62 #define TEN_E5 (0x186A0L) 63 #define TEN_E6 (0xF4240L) 64 #define TEN_E7 (0x989680L) 65 #define TEN_E8 (0x5F5E100L) 66 #define TEN_E9 (0x3B9ACA00L) 67 #define TEN_E19 (0x8AC7230489E80000L) 68 #else 69 #define TEN_E1 (0xA) 70 #define TEN_E2 (0x64) 71 #define TEN_E3 (0x3E8) 72 #define TEN_E4 (0x2710) 73 #define TEN_E5 (0x186A0) 74 #define TEN_E6 (0xF4240) 75 #define TEN_E7 (0x989680) 76 #define TEN_E8 (0x5F5E100) 77 #define TEN_E9 (0x3B9ACA00) 78 #define TEN_E19 (0x8AC7230489E80000) 79 #endif /* USE_L */ 80 #endif /* USE_LL */ 81 82 #define TIMES_TEN(x) (((x) << 3) + ((x) << 1)) 83 #define bitSection(x, mask, shift) (((x) & (mask)) >> (shift)) 84 #define CREATE_DOUBLE_BITS(normalizedM, e) (((normalizedM) & MANTISSA_MASK) | ((static_cast<uint64_t>((e) + E_OFFSET)) << 52)) 85 86 #if defined(USE_LL) 87 #define MANTISSA_MASK (0x000FFFFFFFFFFFFFLL) 88 #define EXPONENT_MASK (0x7FF0000000000000LL) 89 #define NORMAL_MASK (0x0010000000000000LL) 90 #define SIGN_MASK (0x8000000000000000LL) 91 #else 92 #if defined(USE_L) 93 #define MANTISSA_MASK (0x000FFFFFFFFFFFFFL) 94 #define EXPONENT_MASK (0x7FF0000000000000L) 95 #define NORMAL_MASK (0x0010000000000000L) 96 #define SIGN_MASK (0x8000000000000000L) 97 #else 98 #define MANTISSA_MASK (0x000FFFFFFFFFFFFF) 99 #define EXPONENT_MASK (0x7FF0000000000000) 100 #define NORMAL_MASK (0x0010000000000000) 101 #define SIGN_MASK (0x8000000000000000) 102 #endif /* USE_L */ 103 #endif /* USE_LL */ 104 105 #define E_OFFSET (1075) 106 107 #define FLOAT_MANTISSA_MASK (0x007FFFFF) 108 #define FLOAT_EXPONENT_MASK (0x7F800000) 109 #define FLOAT_NORMAL_MASK (0x00800000) 110 #define FLOAT_E_OFFSET (150) 111 112 int32_t 113 simpleAddHighPrecision (uint64_t * arg1, int32_t length, uint64_t arg2) 114 { 115 /* assumes length > 0 */ 116 int32_t index = 1; 117 118 *arg1 += arg2; 119 if (arg2 <= *arg1) 120 return 0; 121 else if (length == 1) 122 return 1; 123 124 while (++arg1[index] == 0 && ++index < length); 125 126 return index == length; 127 } 128 129 int32_t 130 addHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2) 131 { 132 /* addition is limited by length of arg1 as it this function is 133 * storing the result in arg1 */ 134 /* fix for cc (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7): code generated does not 135 * do the temp1 + temp2 + carry addition correct. carry is 64 bit because gcc has 136 * subtle issues when you mix 64 / 32 bit maths. */ 137 uint64_t temp1, temp2, temp3; /* temporary variables to help the SH-4, and gcc */ 138 uint64_t carry; 139 int32_t index; 140 141 if (length1 == 0 || length2 == 0) 142 { 143 return 0; 144 } 145 else if (length1 < length2) 146 { 147 length2 = length1; 148 } 149 150 carry = 0; 151 index = 0; 152 do 153 { 154 temp1 = arg1[index]; 155 temp2 = arg2[index]; 156 temp3 = temp1 + temp2; 157 arg1[index] = temp3 + carry; 158 if (arg2[index] < arg1[index]) 159 carry = 0; 160 else if (arg2[index] != arg1[index]) 161 carry = 1; 162 } 163 while (++index < length2); 164 if (!carry) 165 return 0; 166 else if (index == length1) 167 return 1; 168 169 while (++arg1[index] == 0 && ++index < length1); 170 171 return index == length1; 172 } 173 174 void 175 subtractHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2) 176 { 177 /* assumes arg1 > arg2 */ 178 int32_t index; 179 for (index = 0; index < length1; ++index) 180 arg1[index] = ~arg1[index]; 181 simpleAddHighPrecision (arg1, length1, 1); 182 183 while (length2 > 0 && arg2[length2 - 1] == 0) 184 --length2; 185 186 addHighPrecision (arg1, length1, arg2, length2); 187 188 for (index = 0; index < length1; ++index) 189 arg1[index] = ~arg1[index]; 190 simpleAddHighPrecision (arg1, length1, 1); 191 } 192 193 static uint32_t simpleMultiplyHighPrecision(uint64_t* arg1, int32_t length, uint64_t arg2) { 194 /* assumes arg2 only holds 32 bits of information */ 195 uint64_t product; 196 int32_t index; 197 198 index = 0; 199 product = 0; 200 201 do 202 { 203 product = 204 HIGH_IN_U64 (product) + arg2 * LOW_U32_FROM_PTR (arg1 + index); 205 LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (product); 206 product = 207 HIGH_IN_U64 (product) + arg2 * HIGH_U32_FROM_PTR (arg1 + index); 208 HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (product); 209 } 210 while (++index < length); 211 212 return HIGH_U32_FROM_VAR (product); 213 } 214 215 static void 216 simpleMultiplyAddHighPrecision (uint64_t * arg1, int32_t length, uint64_t arg2, 217 uint32_t * result) 218 { 219 /* Assumes result can hold the product and arg2 only holds 32 bits 220 of information */ 221 uint64_t product; 222 int32_t index, resultIndex; 223 224 index = resultIndex = 0; 225 product = 0; 226 227 do 228 { 229 product = 230 HIGH_IN_U64 (product) + result[at (resultIndex)] + 231 arg2 * LOW_U32_FROM_PTR (arg1 + index); 232 result[at (resultIndex)] = LOW_U32_FROM_VAR (product); 233 ++resultIndex; 234 product = 235 HIGH_IN_U64 (product) + result[at (resultIndex)] + 236 arg2 * HIGH_U32_FROM_PTR (arg1 + index); 237 result[at (resultIndex)] = LOW_U32_FROM_VAR (product); 238 ++resultIndex; 239 } 240 while (++index < length); 241 242 result[at (resultIndex)] += HIGH_U32_FROM_VAR (product); 243 if (result[at (resultIndex)] < HIGH_U32_FROM_VAR (product)) 244 { 245 /* must be careful with ++ operator and macro expansion */ 246 ++resultIndex; 247 while (++result[at (resultIndex)] == 0) 248 ++resultIndex; 249 } 250 } 251 252 #if __BYTE_ORDER != __LITTLE_ENDIAN 253 void simpleMultiplyAddHighPrecisionBigEndianFix(uint64_t* arg1, int32_t length, uint64_t arg2, uint32_t* result) { 254 /* Assumes result can hold the product and arg2 only holds 32 bits 255 of information */ 256 uint64_t product; 257 int32_t index, resultIndex; 258 259 index = resultIndex = 0; 260 product = 0; 261 262 do { 263 product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * LOW_U32_FROM_PTR(arg1 + index); 264 result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product); 265 ++resultIndex; 266 product = HIGH_IN_U64(product) + result[halfAt(resultIndex)] + arg2 * HIGH_U32_FROM_PTR(arg1 + index); 267 result[halfAt(resultIndex)] = LOW_U32_FROM_VAR(product); 268 ++resultIndex; 269 } while (++index < length); 270 271 result[halfAt(resultIndex)] += HIGH_U32_FROM_VAR(product); 272 if (result[halfAt(resultIndex)] < HIGH_U32_FROM_VAR(product)) { 273 /* must be careful with ++ operator and macro expansion */ 274 ++resultIndex; 275 while (++result[halfAt(resultIndex)] == 0) ++resultIndex; 276 } 277 } 278 #endif 279 280 void 281 multiplyHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2, 282 uint64_t * result, int32_t length) 283 { 284 /* assumes result is large enough to hold product */ 285 uint64_t* temp; 286 uint32_t* resultIn32; 287 int32_t count, index; 288 289 if (length1 < length2) 290 { 291 temp = arg1; 292 arg1 = arg2; 293 arg2 = temp; 294 count = length1; 295 length1 = length2; 296 length2 = count; 297 } 298 299 memset (result, 0, sizeof (uint64_t) * length); 300 301 /* length1 > length2 */ 302 resultIn32 = reinterpret_cast<uint32_t*>(result); 303 index = -1; 304 for (count = 0; count < length2; ++count) 305 { 306 simpleMultiplyAddHighPrecision (arg1, length1, LOW_IN_U64 (arg2[count]), 307 resultIn32 + (++index)); 308 #if __BYTE_ORDER == __LITTLE_ENDIAN 309 simpleMultiplyAddHighPrecision(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index)); 310 #else 311 simpleMultiplyAddHighPrecisionBigEndianFix(arg1, length1, HIGH_IN_U64(arg2[count]), resultIn32 + (++index)); 312 #endif 313 } 314 } 315 316 uint32_t 317 simpleAppendDecimalDigitHighPrecision (uint64_t * arg1, int32_t length, uint64_t digit) 318 { 319 /* assumes digit is less than 32 bits */ 320 uint64_t arg; 321 int32_t index = 0; 322 323 digit <<= 32; 324 do 325 { 326 arg = LOW_IN_U64 (arg1[index]); 327 digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); 328 LOW_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); 329 330 arg = HIGH_IN_U64 (arg1[index]); 331 digit = HIGH_IN_U64 (digit) + TIMES_TEN (arg); 332 HIGH_U32_FROM_PTR (arg1 + index) = LOW_U32_FROM_VAR (digit); 333 } 334 while (++index < length); 335 336 return HIGH_U32_FROM_VAR (digit); 337 } 338 339 void 340 simpleShiftLeftHighPrecision (uint64_t * arg1, int32_t length, int32_t arg2) 341 { 342 /* assumes length > 0 */ 343 int32_t index, offset; 344 if (arg2 >= 64) 345 { 346 offset = arg2 >> 6; 347 index = length; 348 349 while (--index - offset >= 0) 350 arg1[index] = arg1[index - offset]; 351 do 352 { 353 arg1[index] = 0; 354 } 355 while (--index >= 0); 356 357 arg2 &= 0x3F; 358 } 359 360 if (arg2 == 0) 361 return; 362 while (--length > 0) 363 { 364 arg1[length] = arg1[length] << arg2 | arg1[length - 1] >> (64 - arg2); 365 } 366 *arg1 <<= arg2; 367 } 368 369 int32_t 370 highestSetBit (uint64_t * y) 371 { 372 uint32_t x; 373 int32_t result; 374 375 if (*y == 0) 376 return 0; 377 378 #if defined(USE_LL) 379 if (*y & 0xFFFFFFFF00000000LL) 380 { 381 x = HIGH_U32_FROM_PTR (y); 382 result = 32; 383 } 384 else 385 { 386 x = LOW_U32_FROM_PTR (y); 387 result = 0; 388 } 389 #else 390 #if defined(USE_L) 391 if (*y & 0xFFFFFFFF00000000L) 392 { 393 x = HIGH_U32_FROM_PTR (y); 394 result = 32; 395 } 396 else 397 { 398 x = LOW_U32_FROM_PTR (y); 399 result = 0; 400 } 401 #else 402 if (*y & 0xFFFFFFFF00000000) 403 { 404 x = HIGH_U32_FROM_PTR (y); 405 result = 32; 406 } 407 else 408 { 409 x = LOW_U32_FROM_PTR (y); 410 result = 0; 411 } 412 #endif /* USE_L */ 413 #endif /* USE_LL */ 414 415 if (x & 0xFFFF0000) 416 { 417 x = bitSection (x, 0xFFFF0000, 16); 418 result += 16; 419 } 420 if (x & 0xFF00) 421 { 422 x = bitSection (x, 0xFF00, 8); 423 result += 8; 424 } 425 if (x & 0xF0) 426 { 427 x = bitSection (x, 0xF0, 4); 428 result += 4; 429 } 430 if (x > 0x7) 431 return result + 4; 432 else if (x > 0x3) 433 return result + 3; 434 else if (x > 0x1) 435 return result + 2; 436 else 437 return result + 1; 438 } 439 440 int32_t 441 lowestSetBit (uint64_t * y) 442 { 443 uint32_t x; 444 int32_t result; 445 446 if (*y == 0) 447 return 0; 448 449 #if defined(USE_LL) 450 if (*y & 0x00000000FFFFFFFFLL) 451 { 452 x = LOW_U32_FROM_PTR (y); 453 result = 0; 454 } 455 else 456 { 457 x = HIGH_U32_FROM_PTR (y); 458 result = 32; 459 } 460 #else 461 #if defined(USE_L) 462 if (*y & 0x00000000FFFFFFFFL) 463 { 464 x = LOW_U32_FROM_PTR (y); 465 result = 0; 466 } 467 else 468 { 469 x = HIGH_U32_FROM_PTR (y); 470 result = 32; 471 } 472 #else 473 if (*y & 0x00000000FFFFFFFF) 474 { 475 x = LOW_U32_FROM_PTR (y); 476 result = 0; 477 } 478 else 479 { 480 x = HIGH_U32_FROM_PTR (y); 481 result = 32; 482 } 483 #endif /* USE_L */ 484 #endif /* USE_LL */ 485 486 if (!(x & 0xFFFF)) 487 { 488 x = bitSection (x, 0xFFFF0000, 16); 489 result += 16; 490 } 491 if (!(x & 0xFF)) 492 { 493 x = bitSection (x, 0xFF00, 8); 494 result += 8; 495 } 496 if (!(x & 0xF)) 497 { 498 x = bitSection (x, 0xF0, 4); 499 result += 4; 500 } 501 502 if (x & 0x1) 503 return result + 1; 504 else if (x & 0x2) 505 return result + 2; 506 else if (x & 0x4) 507 return result + 3; 508 else 509 return result + 4; 510 } 511 512 int32_t 513 highestSetBitHighPrecision (uint64_t * arg, int32_t length) 514 { 515 int32_t highBit; 516 517 while (--length >= 0) 518 { 519 highBit = highestSetBit (arg + length); 520 if (highBit) 521 return highBit + 64 * length; 522 } 523 524 return 0; 525 } 526 527 int32_t 528 lowestSetBitHighPrecision (uint64_t * arg, int32_t length) 529 { 530 int32_t lowBit, index = -1; 531 532 while (++index < length) 533 { 534 lowBit = lowestSetBit (arg + index); 535 if (lowBit) 536 return lowBit + 64 * index; 537 } 538 539 return 0; 540 } 541 542 int32_t 543 compareHighPrecision (uint64_t * arg1, int32_t length1, uint64_t * arg2, int32_t length2) 544 { 545 while (--length1 >= 0 && arg1[length1] == 0); 546 while (--length2 >= 0 && arg2[length2] == 0); 547 548 if (length1 > length2) 549 return 1; 550 else if (length1 < length2) 551 return -1; 552 else if (length1 > -1) 553 { 554 do 555 { 556 if (arg1[length1] > arg2[length1]) 557 return 1; 558 else if (arg1[length1] < arg2[length1]) 559 return -1; 560 } 561 while (--length1 >= 0); 562 } 563 564 return 0; 565 } 566 567 jdouble 568 toDoubleHighPrecision (uint64_t * arg, int32_t length) 569 { 570 int32_t highBit; 571 uint64_t mantissa, test64; 572 uint32_t test; 573 jdouble result; 574 575 while (length > 0 && arg[length - 1] == 0) 576 --length; 577 578 if (length == 0) 579 result = 0.0; 580 else if (length > 16) 581 { 582 DOUBLE_TO_LONGBITS (result) = EXPONENT_MASK; 583 } 584 else if (length == 1) 585 { 586 highBit = highestSetBit (arg); 587 if (highBit <= 53) 588 { 589 highBit = 53 - highBit; 590 mantissa = *arg << highBit; 591 DOUBLE_TO_LONGBITS (result) = 592 CREATE_DOUBLE_BITS (mantissa, -highBit); 593 } 594 else 595 { 596 highBit -= 53; 597 mantissa = *arg >> highBit; 598 DOUBLE_TO_LONGBITS (result) = 599 CREATE_DOUBLE_BITS (mantissa, highBit); 600 601 /* perform rounding, round to even in case of tie */ 602 test = (LOW_U32_FROM_PTR (arg) << (11 - highBit)) & 0x7FF; 603 if (test > 0x400 || ((test == 0x400) && (mantissa & 1))) 604 DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; 605 } 606 } 607 else 608 { 609 highBit = highestSetBit (arg + (--length)); 610 if (highBit <= 53) 611 { 612 highBit = 53 - highBit; 613 if (highBit > 0) 614 { 615 mantissa = 616 (arg[length] << highBit) | (arg[length - 1] >> 617 (64 - highBit)); 618 } 619 else 620 { 621 mantissa = arg[length]; 622 } 623 DOUBLE_TO_LONGBITS (result) = 624 CREATE_DOUBLE_BITS (mantissa, length * 64 - highBit); 625 626 /* perform rounding, round to even in case of tie */ 627 test64 = arg[--length] << highBit; 628 if (test64 > SIGN_MASK || ((test64 == SIGN_MASK) && (mantissa & 1))) 629 DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; 630 else if (test64 == SIGN_MASK) 631 { 632 while (--length >= 0) 633 { 634 if (arg[length] != 0) 635 { 636 DOUBLE_TO_LONGBITS (result) = 637 DOUBLE_TO_LONGBITS (result) + 1; 638 break; 639 } 640 } 641 } 642 } 643 else 644 { 645 highBit -= 53; 646 mantissa = arg[length] >> highBit; 647 DOUBLE_TO_LONGBITS (result) = 648 CREATE_DOUBLE_BITS (mantissa, length * 64 + highBit); 649 650 /* perform rounding, round to even in case of tie */ 651 test = (LOW_U32_FROM_PTR (arg + length) << (11 - highBit)) & 0x7FF; 652 if (test > 0x400 || ((test == 0x400) && (mantissa & 1))) 653 DOUBLE_TO_LONGBITS (result) = DOUBLE_TO_LONGBITS (result) + 1; 654 else if (test == 0x400) 655 { 656 do 657 { 658 if (arg[--length] != 0) 659 { 660 DOUBLE_TO_LONGBITS (result) = 661 DOUBLE_TO_LONGBITS (result) + 1; 662 break; 663 } 664 } 665 while (length > 0); 666 } 667 } 668 } 669 670 return result; 671 } 672 673 static uint64_t simpleMultiplyHighPrecision64(uint64_t* arg1, int32_t length, uint64_t arg2); 674 675 int32_t 676 timesTenToTheEHighPrecision (uint64_t * result, int32_t length, jint e) 677 { 678 /* assumes result can hold value */ 679 uint64_t overflow; 680 int exp10 = e; 681 682 if (e == 0) 683 return length; 684 685 /* bad O(n) way of doing it, but simple */ 686 /* 687 do { 688 overflow = simpleAppendDecimalDigitHighPrecision(result, length, 0); 689 if (overflow) 690 result[length++] = overflow; 691 } while (--e); 692 */ 693 /* Replace the current implementaion which performs a 694 * "multiplication" by 10 e number of times with an actual 695 * multiplication. 10e19 is the largest exponent to the power of ten 696 * that will fit in a 64-bit integer, and 10e9 is the largest exponent to 697 * the power of ten that will fit in a 64-bit integer. Not sure where the 698 * break-even point is between an actual multiplication and a 699 * simpleAappendDecimalDigit() so just pick 10e3 as that point for 700 * now. 701 */ 702 while (exp10 >= 19) 703 { 704 overflow = simpleMultiplyHighPrecision64 (result, length, TEN_E19); 705 if (overflow) 706 result[length++] = overflow; 707 exp10 -= 19; 708 } 709 while (exp10 >= 9) 710 { 711 overflow = simpleMultiplyHighPrecision (result, length, TEN_E9); 712 if (overflow) 713 result[length++] = overflow; 714 exp10 -= 9; 715 } 716 if (exp10 == 0) 717 return length; 718 else if (exp10 == 1) 719 { 720 overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); 721 if (overflow) 722 result[length++] = overflow; 723 } 724 else if (exp10 == 2) 725 { 726 overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); 727 if (overflow) 728 result[length++] = overflow; 729 overflow = simpleAppendDecimalDigitHighPrecision (result, length, 0); 730 if (overflow) 731 result[length++] = overflow; 732 } 733 else if (exp10 == 3) 734 { 735 overflow = simpleMultiplyHighPrecision (result, length, TEN_E3); 736 if (overflow) 737 result[length++] = overflow; 738 } 739 else if (exp10 == 4) 740 { 741 overflow = simpleMultiplyHighPrecision (result, length, TEN_E4); 742 if (overflow) 743 result[length++] = overflow; 744 } 745 else if (exp10 == 5) 746 { 747 overflow = simpleMultiplyHighPrecision (result, length, TEN_E5); 748 if (overflow) 749 result[length++] = overflow; 750 } 751 else if (exp10 == 6) 752 { 753 overflow = simpleMultiplyHighPrecision (result, length, TEN_E6); 754 if (overflow) 755 result[length++] = overflow; 756 } 757 else if (exp10 == 7) 758 { 759 overflow = simpleMultiplyHighPrecision (result, length, TEN_E7); 760 if (overflow) 761 result[length++] = overflow; 762 } 763 else if (exp10 == 8) 764 { 765 overflow = simpleMultiplyHighPrecision (result, length, TEN_E8); 766 if (overflow) 767 result[length++] = overflow; 768 } 769 return length; 770 } 771 772 uint64_t 773 doubleMantissa (jdouble z) 774 { 775 uint64_t m = DOUBLE_TO_LONGBITS (z); 776 777 if ((m & EXPONENT_MASK) != 0) 778 m = (m & MANTISSA_MASK) | NORMAL_MASK; 779 else 780 m = (m & MANTISSA_MASK); 781 782 return m; 783 } 784 785 int32_t 786 doubleExponent (jdouble z) 787 { 788 /* assumes positive double */ 789 int32_t k = HIGH_U32_FROM_VAR (z) >> 20; 790 791 if (k) 792 k -= E_OFFSET; 793 else 794 k = 1 - E_OFFSET; 795 796 return k; 797 } 798 799 uint32_t floatMantissa(jfloat z) { 800 uint32_t m = FLOAT_TO_INTBITS (z); 801 802 if ((m & FLOAT_EXPONENT_MASK) != 0) 803 m = (m & FLOAT_MANTISSA_MASK) | FLOAT_NORMAL_MASK; 804 else 805 m = (m & FLOAT_MANTISSA_MASK); 806 807 return m; 808 } 809 810 int32_t 811 floatExponent (jfloat z) 812 { 813 /* assumes positive float */ 814 int32_t k = FLOAT_TO_INTBITS (z) >> 23; 815 if (k) 816 k -= FLOAT_E_OFFSET; 817 else 818 k = 1 - FLOAT_E_OFFSET; 819 820 return k; 821 } 822 823 /* Allow a 64-bit value in arg2 */ 824 uint64_t 825 simpleMultiplyHighPrecision64 (uint64_t * arg1, int32_t length, uint64_t arg2) 826 { 827 uint64_t intermediate, carry1, carry2, prod1, prod2, sum; 828 uint64_t* pArg1; 829 int32_t index; 830 uint32_t buf32; 831 832 index = 0; 833 intermediate = 0; 834 pArg1 = arg1 + index; 835 carry1 = carry2 = 0; 836 837 do 838 { 839 if ((*pArg1 != 0) || (intermediate != 0)) 840 { 841 prod1 = 842 static_cast<uint64_t>(LOW_U32_FROM_VAR (arg2)) * static_cast<uint64_t>(LOW_U32_FROM_PTR (pArg1)); 843 sum = intermediate + prod1; 844 if ((sum < prod1) || (sum < intermediate)) 845 { 846 carry1 = 1; 847 } 848 else 849 { 850 carry1 = 0; 851 } 852 prod1 = 853 static_cast<uint64_t>(LOW_U32_FROM_VAR (arg2)) * static_cast<uint64_t>(HIGH_U32_FROM_PTR (pArg1)); 854 prod2 = 855 static_cast<uint64_t>(HIGH_U32_FROM_VAR (arg2)) * static_cast<uint64_t>(LOW_U32_FROM_PTR (pArg1)); 856 intermediate = carry2 + HIGH_IN_U64 (sum) + prod1 + prod2; 857 if ((intermediate < prod1) || (intermediate < prod2)) 858 { 859 carry2 = 1; 860 } 861 else 862 { 863 carry2 = 0; 864 } 865 LOW_U32_FROM_PTR (pArg1) = LOW_U32_FROM_VAR (sum); 866 buf32 = HIGH_U32_FROM_PTR (pArg1); 867 HIGH_U32_FROM_PTR (pArg1) = LOW_U32_FROM_VAR (intermediate); 868 intermediate = carry1 + HIGH_IN_U64 (intermediate) 869 + static_cast<uint64_t>(HIGH_U32_FROM_VAR (arg2)) * static_cast<uint64_t>(buf32); 870 } 871 pArg1++; 872 } 873 while (++index < length); 874 return intermediate; 875 } 876