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 |