| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // Original code by Matt McCutchen, see the LICENSE file. |
| 6 |
| 1 #include "BigUnsigned.hh" | 7 #include "BigUnsigned.hh" |
| 2 | 8 |
| 3 // Memory management definitions have moved to the bottom of NumberlikeArray.hh. | 9 // Memory management definitions have moved to the bottom of NumberlikeArray.hh. |
| 4 | 10 |
| 5 // The templates used by these constructors and converters are at the bottom of | 11 // The templates used by these constructors and converters are at the bottom of |
| 6 // BigUnsigned.hh. | 12 // BigUnsigned.hh. |
| 7 | 13 |
| 8 BigUnsigned::BigUnsigned(unsigned long x) { initFromPrimitive (x); } | 14 BigUnsigned::BigUnsigned(unsigned long x) { initFromPrimitive (x); } |
| 9 BigUnsigned::BigUnsigned(unsigned int x) { initFromPrimitive (x); } | 15 BigUnsigned::BigUnsigned(unsigned int x) { initFromPrimitive (x); } |
| 10 BigUnsigned::BigUnsigned(unsigned short x) { initFromPrimitive (x); } | 16 BigUnsigned::BigUnsigned(unsigned short x) { initFromPrimitive (x); } |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 } | 188 } |
| 183 | 189 |
| 184 void BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) { | 190 void BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) { |
| 185 DTRT_ALIASED(this == &a || this == &b, subtract(a, b)); | 191 DTRT_ALIASED(this == &a || this == &b, subtract(a, b)); |
| 186 if (b.len == 0) { | 192 if (b.len == 0) { |
| 187 // If b is zero, copy a. | 193 // If b is zero, copy a. |
| 188 operator =(a); | 194 operator =(a); |
| 189 return; | 195 return; |
| 190 } else if (a.len < b.len) | 196 } else if (a.len < b.len) |
| 191 // If a is shorter than b, the result is negative. | 197 // If a is shorter than b, the result is negative. |
| 198 #ifdef FOXIT_CHROME_BUILD |
| 199 abort(); |
| 200 #else |
| 192 throw "BigUnsigned::subtract: " | 201 throw "BigUnsigned::subtract: " |
| 193 "Negative result in unsigned calculation"; | 202 "Negative result in unsigned calculation"; |
| 203 #endif |
| 194 // Some variables... | 204 // Some variables... |
| 195 bool borrowIn, borrowOut; | 205 bool borrowIn, borrowOut; |
| 196 Blk temp; | 206 Blk temp; |
| 197 Index i; | 207 Index i; |
| 198 // Set preliminary length and make room | 208 // Set preliminary length and make room |
| 199 len = a.len; | 209 len = a.len; |
| 200 allocate(len); | 210 allocate(len); |
| 201 // For each block index that is present in both inputs... | 211 // For each block index that is present in both inputs... |
| 202 for (i = 0, borrowIn = false; i < b.len; i++) { | 212 for (i = 0, borrowIn = false; i < b.len; i++) { |
| 203 temp = a.blk[i] - b.blk[i]; | 213 temp = a.blk[i] - b.blk[i]; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 216 // one does not reverse rollover. | 226 // one does not reverse rollover. |
| 217 for (; i < a.len && borrowIn; i++) { | 227 for (; i < a.len && borrowIn; i++) { |
| 218 borrowIn = (a.blk[i] == 0); | 228 borrowIn = (a.blk[i] == 0); |
| 219 blk[i] = a.blk[i] - 1; | 229 blk[i] = a.blk[i] - 1; |
| 220 } | 230 } |
| 221 /* If there's still a borrow, the result is negative. | 231 /* If there's still a borrow, the result is negative. |
| 222 * Throw an exception, but zero out this object so as to leave it in a | 232 * Throw an exception, but zero out this object so as to leave it in a |
| 223 * predictable state. */ | 233 * predictable state. */ |
| 224 if (borrowIn) { | 234 if (borrowIn) { |
| 225 len = 0; | 235 len = 0; |
| 236 #ifdef FOXIT_CHROME_BUILD |
| 237 abort(); |
| 238 #else |
| 226 throw "BigUnsigned::subtract: Negative result in unsigned calcul
ation"; | 239 throw "BigUnsigned::subtract: Negative result in unsigned calcul
ation"; |
| 240 #endif |
| 227 } else | 241 } else |
| 228 // Copy over the rest of the blocks | 242 // Copy over the rest of the blocks |
| 229 for (; i < a.len; i++) | 243 for (; i < a.len; i++) |
| 230 blk[i] = a.blk[i]; | 244 blk[i] = a.blk[i]; |
| 231 // Zap leading zeros | 245 // Zap leading zeros |
| 232 zapLeadingZeros(); | 246 zapLeadingZeros(); |
| 233 } | 247 } |
| 234 | 248 |
| 235 /* | 249 /* |
| 236 * About the multiplication and division algorithms: | 250 * About the multiplication and division algorithms: |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 * "modWithQuotient" might be a better name for this function, but I would | 393 * "modWithQuotient" might be a better name for this function, but I would |
| 380 * rather not change the name now. | 394 * rather not change the name now. |
| 381 */ | 395 */ |
| 382 void BigUnsigned::divideWithRemainder(const BigUnsigned &b, BigUnsigned &q) { | 396 void BigUnsigned::divideWithRemainder(const BigUnsigned &b, BigUnsigned &q) { |
| 383 /* Defending against aliased calls is more complex than usual because we | 397 /* Defending against aliased calls is more complex than usual because we |
| 384 * are writing to both *this and q. | 398 * are writing to both *this and q. |
| 385 * | 399 * |
| 386 * It would be silly to try to write quotient and remainder to the | 400 * It would be silly to try to write quotient and remainder to the |
| 387 * same variable. Rule that out right away. */ | 401 * same variable. Rule that out right away. */ |
| 388 if (this == &q) | 402 if (this == &q) |
| 403 #ifdef FOXIT_CHROME_BUILD |
| 404 abort(); |
| 405 #else |
| 389 throw "BigUnsigned::divideWithRemainder: Cannot write quotient a
nd remainder into the same variable"; | 406 throw "BigUnsigned::divideWithRemainder: Cannot write quotient a
nd remainder into the same variable"; |
| 407 #endif |
| 390 /* Now *this and q are separate, so the only concern is that b might be | 408 /* Now *this and q are separate, so the only concern is that b might be |
| 391 * aliased to one of them. If so, use a temporary copy of b. */ | 409 * aliased to one of them. If so, use a temporary copy of b. */ |
| 392 if (this == &b || &q == &b) { | 410 if (this == &b || &q == &b) { |
| 393 BigUnsigned tmpB(b); | 411 BigUnsigned tmpB(b); |
| 394 divideWithRemainder(tmpB, q); | 412 divideWithRemainder(tmpB, q); |
| 395 return; | 413 return; |
| 396 } | 414 } |
| 397 | 415 |
| 398 /* | 416 /* |
| 399 * Knuth's definition of mod (which this function uses) is somewhat | 417 * Knuth's definition of mod (which this function uses) is somewhat |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 for (; i < a2->len; i++) | 607 for (; i < a2->len; i++) |
| 590 blk[i] = a2->blk[i]; | 608 blk[i] = a2->blk[i]; |
| 591 len = a2->len; | 609 len = a2->len; |
| 592 zapLeadingZeros(); | 610 zapLeadingZeros(); |
| 593 } | 611 } |
| 594 | 612 |
| 595 void BigUnsigned::bitShiftLeft(const BigUnsigned &a, int b) { | 613 void BigUnsigned::bitShiftLeft(const BigUnsigned &a, int b) { |
| 596 DTRT_ALIASED(this == &a, bitShiftLeft(a, b)); | 614 DTRT_ALIASED(this == &a, bitShiftLeft(a, b)); |
| 597 if (b < 0) { | 615 if (b < 0) { |
| 598 if (b << 1 == 0) | 616 if (b << 1 == 0) |
| 617 #ifdef FOXIT_CHROME_BUILD |
| 618 abort(); |
| 619 #else |
| 599 throw "BigUnsigned::bitShiftLeft: " | 620 throw "BigUnsigned::bitShiftLeft: " |
| 600 "Pathological shift amount not implemented"; | 621 "Pathological shift amount not implemented"; |
| 622 #endif |
| 601 else { | 623 else { |
| 602 bitShiftRight(a, -b); | 624 bitShiftRight(a, -b); |
| 603 return; | 625 return; |
| 604 } | 626 } |
| 605 } | 627 } |
| 606 Index shiftBlocks = b / N; | 628 Index shiftBlocks = b / N; |
| 607 unsigned int shiftBits = b % N; | 629 unsigned int shiftBits = b % N; |
| 608 // + 1: room for high bits nudged left into another block | 630 // + 1: room for high bits nudged left into another block |
| 609 len = a.len + shiftBlocks + 1; | 631 len = a.len + shiftBlocks + 1; |
| 610 allocate(len); | 632 allocate(len); |
| 611 Index i, j; | 633 Index i, j; |
| 612 for (i = 0; i < shiftBlocks; i++) | 634 for (i = 0; i < shiftBlocks; i++) |
| 613 blk[i] = 0; | 635 blk[i] = 0; |
| 614 for (j = 0, i = shiftBlocks; j <= a.len; j++, i++) | 636 for (j = 0, i = shiftBlocks; j <= a.len; j++, i++) |
| 615 blk[i] = getShiftedBlock(a, j, shiftBits); | 637 blk[i] = getShiftedBlock(a, j, shiftBits); |
| 616 // Zap possible leading zero | 638 // Zap possible leading zero |
| 617 if (blk[len - 1] == 0) | 639 if (blk[len - 1] == 0) |
| 618 len--; | 640 len--; |
| 619 } | 641 } |
| 620 | 642 |
| 621 void BigUnsigned::bitShiftRight(const BigUnsigned &a, int b) { | 643 void BigUnsigned::bitShiftRight(const BigUnsigned &a, int b) { |
| 622 DTRT_ALIASED(this == &a, bitShiftRight(a, b)); | 644 DTRT_ALIASED(this == &a, bitShiftRight(a, b)); |
| 623 if (b < 0) { | 645 if (b < 0) { |
| 624 if (b << 1 == 0) | 646 if (b << 1 == 0) |
| 647 #ifdef FOXIT_CHROME_BUILD |
| 648 abort(); |
| 649 #else |
| 625 throw "BigUnsigned::bitShiftRight: " | 650 throw "BigUnsigned::bitShiftRight: " |
| 626 "Pathological shift amount not implemented"; | 651 "Pathological shift amount not implemented"; |
| 652 #endif |
| 627 else { | 653 else { |
| 628 bitShiftLeft(a, -b); | 654 bitShiftLeft(a, -b); |
| 629 return; | 655 return; |
| 630 } | 656 } |
| 631 } | 657 } |
| 632 // This calculation is wacky, but expressing the shift as a left bit shi
ft | 658 // This calculation is wacky, but expressing the shift as a left bit shi
ft |
| 633 // within each block lets us use getShiftedBlock. | 659 // within each block lets us use getShiftedBlock. |
| 634 Index rightShiftBlocks = (b + N - 1) / N; | 660 Index rightShiftBlocks = (b + N - 1) / N; |
| 635 unsigned int leftShiftBits = N * rightShiftBlocks - b; | 661 unsigned int leftShiftBits = N * rightShiftBlocks - b; |
| 636 // Now (N * rightShiftBlocks - leftShiftBits) == b | 662 // Now (N * rightShiftBlocks - leftShiftBits) == b |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 } | 698 } |
| 673 | 699 |
| 674 // Postfix increment: same as prefix | 700 // Postfix increment: same as prefix |
| 675 void BigUnsigned::operator ++(int) { | 701 void BigUnsigned::operator ++(int) { |
| 676 operator ++(); | 702 operator ++(); |
| 677 } | 703 } |
| 678 | 704 |
| 679 // Prefix decrement | 705 // Prefix decrement |
| 680 void BigUnsigned::operator --() { | 706 void BigUnsigned::operator --() { |
| 681 if (len == 0) | 707 if (len == 0) |
| 708 #ifdef FOXIT_CHROME_BUILD |
| 709 abort(); |
| 710 #else |
| 682 throw "BigUnsigned::operator --(): Cannot decrement an unsigned
zero"; | 711 throw "BigUnsigned::operator --(): Cannot decrement an unsigned
zero"; |
| 712 #endif |
| 683 Index i; | 713 Index i; |
| 684 bool borrow = true; | 714 bool borrow = true; |
| 685 for (i = 0; borrow; i++) { | 715 for (i = 0; borrow; i++) { |
| 686 borrow = (blk[i] == 0); | 716 borrow = (blk[i] == 0); |
| 687 blk[i]--; | 717 blk[i]--; |
| 688 } | 718 } |
| 689 // Zap possible leading zero (there can only be one) | 719 // Zap possible leading zero (there can only be one) |
| 690 if (blk[len - 1] == 0) | 720 if (blk[len - 1] == 0) |
| 691 len--; | 721 len--; |
| 692 } | 722 } |
| 693 | 723 |
| 694 // Postfix decrement: same as prefix | 724 // Postfix decrement: same as prefix |
| 695 void BigUnsigned::operator --(int) { | 725 void BigUnsigned::operator --(int) { |
| 696 operator --(); | 726 operator --(); |
| 697 } | 727 } |
| OLD | NEW |