1 9 package org.jscience.mathematics.numbers; 10 11 import java.io.IOException ; 12 13 import javolution.context.ConcurrentContext; 14 import javolution.context.PoolContext; 15 import javolution.context.PoolContext.Reference; 16 import javolution.context.ConcurrentContext.Logic; 17 import javolution.context.LocalContext; 18 import javolution.lang.MathLib; 19 import javolution.text.Text; 20 import javolution.text.TextBuilder; 21 import javolution.text.TextFormat; 22 import javolution.text.TypeFormat; 23 import javolution.xml.XMLFormat; 24 import javolution.xml.stream.XMLStreamException; 25 import static org.jscience.mathematics.numbers.Calculus.*; 26 27 53 public final class LargeInteger extends Number <LargeInteger> { 54 55 59 public static final LocalContext.Reference<TextFormat<LargeInteger>> FORMAT = new LocalContext.Reference<TextFormat<LargeInteger>>( 60 Format.INSTANCE); 61 62 67 public static final XMLFormat<LargeInteger> XML = new XMLFormat<LargeInteger>( 68 LargeInteger.class) { 69 70 @Override 71 public LargeInteger newInstance(Class <LargeInteger> cls, 72 InputElement xml) throws XMLStreamException { 73 return LargeInteger.valueOf(xml.getAttribute("value")); 74 } 75 76 public void write(LargeInteger li, OutputElement xml) 77 throws XMLStreamException { 78 xml.setAttribute("value", li.toText()); 79 } 80 81 public void read(InputElement xml, LargeInteger li) { 82 } 84 }; 85 86 89 public static final LargeInteger ZERO = new LargeInteger(1); 90 static { 91 ZERO._size = 0; 92 ZERO._words[0] = 0; 93 } 95 96 99 public static final LargeInteger ONE = new LargeInteger(1); 100 static { 101 ONE._size = 1; 102 ONE._words[0] = 1; 103 } 104 105 108 private LargeInteger _remainder; 109 110 113 private boolean _isNegative; 114 115 119 private int _size; 120 121 125 private final long[] _words; 126 127 132 private LargeInteger(int wordLength) { 133 _words = new long[wordLength]; 134 } 135 136 142 public static LargeInteger valueOf(long value) { 143 if (value == 0) 144 return LargeInteger.ZERO; 145 if (value == 1) 146 return LargeInteger.ONE; 147 if (value == Long.MIN_VALUE) 148 return LargeInteger.LONG_MIN_VALUE; 149 LargeInteger li = FACTORY_4.object(); 150 boolean negative = li._isNegative = value < 0; 151 li._words[0] = negative ? -value : value; 152 li._size = 1; 153 return li; 154 } 155 156 173 public static LargeInteger valueOf(byte[] bytes, int offset, int length) { 174 LargeInteger z = LargeInteger.newInstance(((length * 8 + 1) / 63) + 1); 177 final boolean isNegative = bytes[offset] < 0; 178 int wordIndex = 0; 179 int bitIndex = 0; 180 z._words[0] = 0; 181 for (int i = offset + length; i > offset; bitIndex += 8) { 182 long bits = (isNegative ? ~bytes[--i] : bytes[--i]) & MASK_8; 183 if (bitIndex < 63 - 8) { 184 z._words[wordIndex] |= bits << bitIndex; 185 } else { z._words[wordIndex] |= (bits << bitIndex) & MASK_63; 187 bitIndex -= 63; z._words[++wordIndex] = bits >> -bitIndex; 189 } 190 } 191 while (z._words[wordIndex] == 0) { 193 if (--wordIndex < 0) { 194 break; 195 } 196 } 197 z._size = wordIndex + 1; 198 z._isNegative = isNegative; 199 200 if (isNegative) { if (z._size > 0) { 203 z._size = add(z._words, z._size, ONE._words, 1, z._words); 204 } else { 205 z._size = add(ONE._words, 1, z._words, 0, z._words); 206 } 207 } 208 return z; 209 } 210 211 218 public static LargeInteger valueOf(CharSequence chars) { 219 return FORMAT.get().parse(chars); 220 } 221 222 234 public static LargeInteger valueOf(CharSequence chars, int radix) { 235 TextFormat.Cursor cursor = TextFormat.Cursor.newInstance(0, chars 236 .length()); 237 LargeInteger li = Format.INSTANCE.parse(chars, radix, cursor); 238 TextFormat.Cursor.recycle(cursor); 239 return li; 240 } 241 242 249 public static LargeInteger valueOf(java.math.BigInteger bigInteger) { 250 byte[] bytes = bigInteger.toByteArray(); 251 return LargeInteger.valueOf(bytes, 0, bytes.length); 252 } 253 254 260 public boolean isPositive() { 261 return !_isNegative && (_size != 0); 262 } 263 264 269 public boolean isNegative() { 270 return _isNegative; 271 } 272 273 278 public boolean isZero() { 279 return _size == 0; 280 } 281 282 288 public int signum() { 289 return _isNegative ? -1 : (_size == 0) ? 0 : 1; 290 } 291 292 297 public boolean isEven() { 298 return (_words[0] & 1) == 0; 299 } 300 301 306 public boolean isOdd() { 307 return (_words[0] & 1) != 0; 308 } 309 310 316 public int bitLength() { 317 if (_size == 0) 318 return 0; 319 final int n = _size - 1; 320 final int bitLength = MathLib.bitLength(_words[n]) + (n << 6) - n; 321 return (this.isNegative() && this.isPowerOfTwo()) ? bitLength - 1 322 : bitLength; 323 } 324 325 331 public int digitLength() { 332 int bitLength = this.bitLength(); 333 int min = (int) (bitLength * BITS_TO_DIGITS) + 1; 334 int max = (int) ((bitLength + 1) * BITS_TO_DIGITS) + 1; 335 if (min == max) 336 return min; 337 return (LargeInteger.ONE.times10pow(min + 1).isLargerThan(this)) ? min 338 : min + 1; 339 } 340 341 private static final double BITS_TO_DIGITS = MathLib.LOG2 / MathLib.LOG10; 342 343 350 public boolean isPowerOfTwo() { 351 if (_size == 0) 352 return false; 353 final int n = _size - 1; 354 for (int j = 0; j < n; j++) { 355 if (_words[j] != 0) 356 return false; 357 } 358 final int bitLength = MathLib.bitLength(_words[n]); 359 return _words[n] == (1L << (bitLength - 1)); 360 } 361 362 368 public int getLowestSetBit() { 369 if (_size == 0) 370 return -1; 371 for (int i = 0;; i++) { 372 long w = _words[i]; 373 if (w == 0) 374 continue; 375 for (int j = 0;; j++) { 376 if (((1L << j) & w) != 0) 377 return i * 63 + j; 378 } 379 } 380 } 381 382 391 public LargeInteger getRemainder() { 392 return _remainder; 393 } 394 395 402 public boolean isLargerThan(LargeInteger that) { 403 return (this._size > that._size) 404 || ((this._size == that._size) && Calculus.compare(this._words, 405 that._words, this._size) > 0); 406 } 407 408 426 public int toByteArray(byte[] bytes, int offset) { 427 int bytesLength = (bitLength() >> 3) + 1; 428 int wordIndex = 0; 429 int bitIndex = 0; 430 if (_isNegative) { 431 long word = _words[0] - 1; 432 long borrow = word >> 63; word = ~word & MASK_63; 434 for (int i = bytesLength + offset; i > offset; bitIndex += 8) { 435 if (bitIndex < 63 - 8) { 436 bytes[--i] = (byte) word; 437 word >>= 8; 438 } else { byte bits = (byte) word; 440 word = (++wordIndex < _size) ? _words[wordIndex] + borrow 441 : borrow; 442 borrow = word >> 63; word = ~word & MASK_63; 444 bitIndex -= 63; bytes[--i] = (byte) ((word << -bitIndex) | bits); 446 word >>= (8 + bitIndex); 447 } 448 } 449 } else { 450 if (_size != 0) { 451 long word = _words[0]; 452 for (int i = bytesLength + offset; i > offset; bitIndex += 8) { 453 if (bitIndex < 63 - 8) { 454 bytes[--i] = (byte) word; 455 word >>= 8; 456 } else { byte bits = (byte) word; 458 word = (++wordIndex < _size) ? _words[wordIndex] : 0; 459 bitIndex -= 63; bytes[--i] = (byte) ((word << -bitIndex) | bits); 461 word >>= (8 + bitIndex); 462 } 463 } 464 } else { bytes[offset] = 0; 466 } 467 } 468 return bytesLength; 469 } 470 471 476 public LargeInteger opposite() { 477 if (_size == 0) 478 return LargeInteger.ZERO; 479 LargeInteger li = LargeInteger.newInstance(_size); 480 System.arraycopy(_words, 0, li._words, 0, _size); 481 li._size = _size; 482 li._isNegative = !_isNegative; 483 return li; 484 } 485 486 493 public LargeInteger plus(long value) { 494 return this.plus(LargeInteger.valueOf(value)); 495 } 496 497 503 public LargeInteger plus(LargeInteger that) { 504 if (this._size < that._size) return that.plus(this); 506 if ((this._isNegative != that._isNegative) && (that._size != 0)) 507 return this.minus(that.opposite()); LargeInteger li = LargeInteger.newInstance(_size + 1); 509 li._size = Calculus.add(_words, _size, that._words, that._size, 510 li._words); 511 li._isNegative = _isNegative; 512 return li; 513 } 514 515 522 public LargeInteger minus(LargeInteger that) { 523 if ((this._isNegative != that._isNegative) && (that._size != 0)) 524 return this.plus(that.opposite()); if (that.isLargerThan(this)) return that.minus(this).opposite(); 527 LargeInteger li = LargeInteger.newInstance(this._size); 528 li._size = Calculus.subtract(_words, _size, that._words, that._size, 529 li._words); 530 li._isNegative = this._isNegative && (li._size != 0); 531 return li; 532 } 533 534 541 public LargeInteger times(long multiplier) { 542 if ((this._size == 0) || (multiplier == 0)) 543 return LargeInteger.ZERO; 544 if (multiplier < 0) 545 return ((multiplier == Long.MIN_VALUE) ? this.shiftLeft(63) : this 546 .times(-multiplier)).opposite(); 547 LargeInteger li = LargeInteger.newInstance(_size + 1); 548 li._size = Calculus.multiply(_words, _size, multiplier, li._words); 549 li._isNegative = _isNegative; 550 return li; 551 } 552 553 559 public LargeInteger times(LargeInteger that) { 560 if (that._size > this._size) return that.times(this); 562 if (that._size <= 1) return this.times(that.longValue()); 564 if (that._size < 10) { LargeInteger li = LargeInteger.newInstance(this._size + that._size); 566 li._size = Calculus.multiply(this._words, this._size, that._words, 567 that._size, li._words); 568 li._isNegative = (this._isNegative != that._isNegative); 569 return li; 570 } else if (that._size < 20) { int n = (that._size >> 1) + (that._size & 1); 572 LargeInteger b = this.high(n); 574 LargeInteger a = this.low(n); 575 LargeInteger d = (this == that) ? b : that.high(n); 577 LargeInteger c = (this == that) ? a : that.low(n); 578 LargeInteger ab = a.plus(b); 579 LargeInteger cd = (this == that) ? ab : c.plus(d); 580 LargeInteger abcd = ab.times(cd); 581 LargeInteger ac = a.times(c); 582 LargeInteger bd = b.times(d); 583 return ac.plus(abcd.minus(ac.plus(bd)).shiftWordLeft(n)).plus( 585 bd.shiftWordLeft(n << 1)); 586 } else { PoolContext.enter(); 588 try { 589 int n = (that._size >> 1) + (that._size & 1); 590 LargeInteger b = this.high(n); 592 LargeInteger a = this.low(n); 593 LargeInteger d = (this == that) ? b : that.high(n); 595 LargeInteger c = (this == that) ? a : that.low(n); 596 LargeInteger ab = a.plus(b); 597 LargeInteger cd = (this == that) ? ab : c.plus(d); 598 Reference<LargeInteger> ac = Reference.newInstance(); 599 Reference<LargeInteger> bd = Reference.newInstance(); 600 Reference<LargeInteger> abcd = Reference.newInstance(); 601 ConcurrentContext.enter(); 602 try { ConcurrentContext.execute(MULTIPLY, ab, cd, abcd); 604 ConcurrentContext.execute(MULTIPLY, a, c, ac); 605 ConcurrentContext.execute(MULTIPLY, b, d, bd); 606 } finally { 607 ConcurrentContext.exit(); 608 } 609 LargeInteger li = ac.get().plus( 611 abcd.get().minus(ac.get().plus(bd.get())) 612 .shiftWordLeft(n)).plus( 613 bd.get().shiftWordLeft(n << 1)); 614 return li.export(); 615 } finally { 616 PoolContext.exit(); 617 } 618 } 619 } 620 621 private LargeInteger high(int w) { LargeInteger li = LargeInteger.newInstance(_size - w); 623 li._isNegative = _isNegative; 624 li._size = _size - w; 625 System.arraycopy(_words, w, li._words, 0, _size - w); 626 return li; 627 } 628 629 private LargeInteger low(int w) { LargeInteger li = LargeInteger.newInstance(w); 631 li._isNegative = _isNegative; 632 System.arraycopy(_words, 0, li._words, 0, w); 633 for (int i = w; i > 0; i--) { 634 if (_words[i - 1] != 0) { 635 li._size = i; 636 return li; 637 } 638 } return LargeInteger.ZERO; 640 } 641 642 private LargeInteger shiftWordLeft(int w) { if (_size == 0) 644 return LargeInteger.ZERO; 645 LargeInteger li = LargeInteger.newInstance(w + _size); 646 li._isNegative = _isNegative; 647 li._size = w + _size; 648 for (int i = 0; i < w;) { 649 li._words[i++] = 0; 650 } 651 System.arraycopy(_words, 0, li._words, w, _size); 652 return li; 653 } 654 655 private static final Logic MULTIPLY = new Logic() { 656 public void run() { 657 LargeInteger left = getArgument(0); 658 LargeInteger right = getArgument(1); 659 PoolContext.Reference<LargeInteger> result = getArgument(2); 660 result.set(left.times(right)); } 662 }; 663 664 674 public LargeInteger divide(int divisor) { 675 if (divisor == 0) 676 throw new ArithmeticException ("Division by zero"); 677 if (divisor == Integer.MIN_VALUE) { LargeInteger li = this.times2pow(-31).copy(); 679 li._isNegative = !_isNegative && (li._size != 0); 680 li._remainder = _isNegative ? LargeInteger 681 .valueOf(-(_words[0] & MASK_31)) : LargeInteger 682 .valueOf(_words[0] & MASK_31); 683 return li; 684 } 685 LargeInteger li = LargeInteger.newInstance(_size); 686 long rem = Calculus.divide(_words, _size, MathLib.abs(divisor), 687 li._words); 688 li._size = (_size > 0) && (li._words[_size - 1] == 0L) ? _size - 1 689 : _size; 690 li._isNegative = (_isNegative != (divisor < 0)) && (li._size != 0); 691 li._remainder = LargeInteger.valueOf(_isNegative ? -rem : rem); 692 return li; 693 } 694 695 705 public LargeInteger divide(LargeInteger that) { 706 if ((that._size <= 1) && ((that._words[0] >> 32) == 0)) 707 return divide(that.intValue()); 708 LargeInteger result; 709 LargeInteger remainder; 710 PoolContext.enter(); 711 try { 712 LargeInteger thisAbs = this.abs(); 713 LargeInteger thatAbs = that.abs(); 714 int precision = thisAbs.bitLength() - thatAbs.bitLength() + 1; 715 if (precision <= 0) { 716 result = LargeInteger.ZERO; 717 remainder = this; 718 } else { 719 LargeInteger thatReciprocal = thatAbs.inverseScaled(precision); 720 result = thisAbs.times(thatReciprocal); 721 result = result.shiftRight(thisAbs.bitLength() + 1); 722 723 remainder = thisAbs.minus(thatAbs.times(result)); 725 if (remainder.compareTo(thatAbs) >= 0) { 726 remainder = remainder.minus(thatAbs); 727 result = result.plus(LargeInteger.ONE); 728 if (remainder.compareTo(thatAbs) >= 0) 729 throw new Error ("Verification error for " + this + "/" 730 + that + ", please submit a bug report."); 731 } else if (remainder.isNegative()) { 732 remainder = remainder.plus(thatAbs); 733 result = result.minus(ONE); 734 if (remainder.isNegative()) 735 throw new Error ("Verification error for " + this + "/" 736 + that + ", please submit a bug report."); 737 } 738 } 739 } finally { 740 PoolContext.exit(); 741 } 742 LargeInteger li = result.copy(); 744 li._isNegative = (this._isNegative != that._isNegative) 745 && (result._size != 0); 746 li._remainder = remainder.copy(); 747 li._remainder._isNegative = this._isNegative && (remainder._size != 0); 748 return li; 749 } 750 751 762 public LargeInteger remainder(LargeInteger that) { 763 return this.divide(that).getRemainder(); 764 } 765 766 773 public LargeInteger inverseScaled(int precision) { 774 if (precision <= 30) { long divisor = this.shiftRight(this.bitLength() - precision - 1)._words[0]; 776 long dividend = 1L << (precision * 2 + 1); 777 return (this.isNegative()) ? LargeInteger.valueOf(-dividend 778 / divisor) : LargeInteger.valueOf(dividend / divisor); 779 } else { LargeInteger x = inverseScaled(precision / 2 + 1); LargeInteger thisTrunc = shiftRight(bitLength() - (precision + 2)); 782 LargeInteger prod = thisTrunc.times(x).times(x); 783 int diff = 2 * (precision / 2 + 2); 784 LargeInteger prodTrunc = prod.shiftRight(diff); 785 LargeInteger xPad = x.shiftLeft(precision - precision / 2 - 1); 786 LargeInteger tmp = xPad.minus(prodTrunc); 787 return xPad.plus(tmp); 788 } 789 } 790 791 801 public LargeInteger mod(LargeInteger m) { 802 final LargeInteger li = m.isLargerThan(this) ? this : this.divide(m) 803 .getRemainder(); 804 return (this._isNegative == m._isNegative) ? li : li.plus(m); 805 } 806 807 817 public LargeInteger modInverse(LargeInteger m) { 818 if (!m.isPositive()) 819 throw new ArithmeticException ("Modulus is not a positive number"); 820 PoolContext.enter(); 821 try { 822 LargeInteger a = this; 824 LargeInteger b = m; 825 LargeInteger p = ONE; 826 LargeInteger q = ZERO; 827 LargeInteger r = ZERO; 828 LargeInteger s = ONE; 829 while (!b.isZero()) { 830 LargeInteger quot = a.divide(b); 831 LargeInteger c = quot.getRemainder(); 832 a = b; 833 b = c; 834 LargeInteger new_r = p.minus(quot.times(r)); 835 LargeInteger new_s = q.minus(quot.times(s)); 836 p = r; 837 q = s; 838 r = new_r; 839 s = new_s; 840 } 841 if (!a.abs().equals(ONE)) throw new ArithmeticException ("GCD(" + this + ", " + m + ") = " 843 + a); 844 if (a.isNegative()) 845 return p.opposite().mod(m).export(); 846 return p.mod(m).export(); 847 } finally { 848 PoolContext.exit(); 849 } 850 } 851 852 862 public LargeInteger modPow(LargeInteger exp, LargeInteger m) { 863 if (!m.isPositive()) 864 throw new ArithmeticException ("Modulus is not a positive number"); 865 if (exp.isPositive()) { 866 PoolContext.enter(); 867 try { 868 LargeInteger pow2 = this.mod(m); 869 LargeInteger result = null; 870 while (exp.compareTo(ONE) >= 0) { if (exp.isOdd()) { 872 result = (result == null) ? pow2 : result.times(pow2) 873 .mod(m); 874 } 875 pow2 = pow2.times(pow2).mod(m); 876 exp = exp.shiftRight(1); 877 } 878 return result.export(); 879 } finally { 880 PoolContext.exit(); 881 } 882 } else if (exp.isNegative()) { 883 return this.modPow(exp.opposite(), m).modInverse(m); 884 } else { return LargeInteger.ONE; 886 } 887 } 888 889 897 public LargeInteger gcd(LargeInteger that) { 898 if (this.isZero()) 899 return that; 900 if (that.isZero()) 901 return this; 902 LargeInteger u = this.copy(); 904 u._isNegative = false; LargeInteger v = that.copy(); 906 v._isNegative = false; 908 while (MathLib.abs(u._size - v._size) > 1) { 910 LargeInteger tmp = u.divide(v); 911 LargeInteger rem = tmp.getRemainder(); 912 u = v; 913 v = rem; 914 if (v.isZero()) 915 return u; 916 } 917 918 final int uShift = u.getLowestSetBit(); 921 u.shiftRightSelf(uShift); 922 final int vShift = v.getLowestSetBit(); 923 v.shiftRightSelf(vShift); 924 925 while (true) { 927 if (u.compareTo(v) < 0) { 930 v.subtract(u); 931 } else { 932 u.subtract(v); 933 LargeInteger tmp = u; 934 u = v; 935 v = tmp; } 937 v.shiftRightSelf(); 938 if (v.isZero()) 939 break; 940 v.shiftRightSelf(v.getLowestSetBit()); 941 } 942 return u.shiftLeft(MathLib.min(uShift, vShift)); 943 } 944 945 private void shiftRightSelf() { 946 if (_size == 0) 947 return; 948 _size = Calculus.shiftRight(0, 1, _words, _size, _words); 949 } 950 951 private void shiftRightSelf(int n) { 952 if ((n == 0) || (_size == 0)) 953 return; 954 int wordShift = n < 63 ? 0 : n / 63; 955 int bitShift = n - ((wordShift << 6) - wordShift); _size = Calculus.shiftRight(wordShift, bitShift, _words, _size, _words); 957 } 958 959 private void subtract(LargeInteger that) { _size = Calculus.subtract(_words, _size, that._words, that._size, 961 _words); 962 } 963 964 969 public LargeInteger abs() { 970 if (_isNegative) 971 return this.opposite(); 972 return this; 973 } 974 975 984 public LargeInteger shiftLeft(int n) { 985 if (n < 0) 986 return shiftRight(-n); 987 if (_size == 0) 988 return LargeInteger.ZERO; 989 final int wordShift = n < 63 ? 0 : n / 63; 990 final int bitShift = n - wordShift * 63; 991 LargeInteger li = newInstance(_size + wordShift + 1); 992 li._isNegative = _isNegative; 993 li._size = Calculus.shiftLeft(wordShift, bitShift, _words, _size, 994 li._words); 995 return li; 996 } 997 998 1007 public LargeInteger shiftRight(int n) { 1008 LargeInteger li = this.times2pow(-n); 1009 return (_isNegative) && (n > 0) && (isShiftRightCorrection(n)) ? li 1010 .minus(LargeInteger.ONE) : li; 1011 } 1012 1013 private boolean isShiftRightCorrection(int n) { 1016 int wordShift = n < 63 ? 0 : n / 63; 1017 int bitShift = n - ((wordShift << 6) - wordShift); int i = wordShift; 1019 boolean bitsLost = (bitShift != 0) 1020 && (_words[i] << (64 - bitShift)) != 0; 1021 while ((!bitsLost) && --i >= 0) { 1022 bitsLost = _words[i--] != 0; 1023 } 1024 return bitsLost; 1025 } 1026 1027 1037 public LargeInteger times2pow(int n) { 1038 if (n >= 0) 1039 return shiftLeft(n); 1040 n = -n; int wordShift = n < 63 ? 0 : n / 63; 1042 int bitShift = n - ((wordShift << 6) - wordShift); if (_size <= wordShift) return LargeInteger.ZERO; 1045 LargeInteger li = newInstance(_size - wordShift); 1046 li._size = Calculus.shiftRight(wordShift, bitShift, _words, _size, 1047 li._words); 1048 li._isNegative = _isNegative && (li._size != 0); 1049 return li; 1050 } 1051 1052 1061 public LargeInteger times10pow(int n) { 1062 if (this._size == 0) 1063 return LargeInteger.ZERO; 1064 if (n >= 0) { 1065 int bitLength = (int) (n * DIGITS_TO_BITS); 1066 LargeInteger li = newInstance(_size + (bitLength / 63) + 1); li._isNegative = _isNegative; 1068 int i = (n >= LONG_POW_5.length) ? LONG_POW_5.length - 1 : n; 1069 li._size = Calculus.multiply(_words, _size, LONG_POW_5[i], 1070 li._words); 1071 for (int j = n - i; j != 0; j -= i) { 1072 i = (j >= LONG_POW_5.length) ? LONG_POW_5.length - 1 : j; 1073 li._size = Calculus.multiply(li._words, li._size, 1074 LONG_POW_5[i], li._words); 1075 } 1076 final int wordShift = n < 63 ? 0 : n / 63; 1078 final int bitShift = n - ((wordShift << 6) - wordShift); li._size = Calculus.shiftLeft(wordShift, bitShift, li._words, 1080 li._size, li._words); 1081 return li; 1082 } else { n = -n; 1084 final int wordShift = n < 63 ? 0 : n / 63; 1086 final int bitShift = n - ((wordShift << 6) - wordShift); if (_size <= wordShift) return LargeInteger.ZERO; 1089 LargeInteger li = newInstance(_size - wordShift); 1090 li._size = Calculus.shiftRight(wordShift, bitShift, _words, _size, 1091 li._words); 1092 for (int j = n; j != 0;) { int i = (n >= INT_POW_5.length) ? INT_POW_5.length - 1 : n; 1094 Calculus.divide(li._words, li._size, INT_POW_5[i], li._words); 1095 if ((li._size > 0) && (li._words[li._size - 1] == 0L)) { 1096 li._size--; 1097 } 1098 j -= i; 1099 } 1100 li._isNegative = _isNegative && (li._size != 0); 1101 return li; 1102 } 1103 } 1104 1105 private static double DIGITS_TO_BITS = MathLib.LOG10 / MathLib.LOG2; 1106 1107 private static int[] INT_POW_5 = new int[] { 1, 5, 25, 125, 625, 3125, 1108 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1109 1220703125 }; 1110 1111 private static long[] LONG_POW_5 = new long[] { 1L, 5L, 25L, 125L, 625L, 1112 3125L, 15625L, 78125L, 390625L, 1953125L, 9765625L, 48828125L, 1113 244140625L, 1220703125L, 6103515625L, 30517578125L, 152587890625L, 1114 762939453125L, 3814697265625L, 19073486328125L, 95367431640625L, 1115 476837158203125L, 2384185791015625L, 11920928955078125L, 1116 59604644775390625L, 298023223876953125L, 1490116119384765625L, 1117 7450580596923828125L }; 1118 1119 1124 public Text toText() { 1125 return FORMAT.get().format(this); 1126 } 1127 1128 1134 public Text toText(int radix) { 1135 TextBuilder tmp = TextBuilder.newInstance(); 1136 Format.INSTANCE.format(this, radix, tmp); 1137 Text txt = tmp.toText(); 1138 TextBuilder.recycle(tmp); 1139 return txt; 1140 } 1141 1142 1149 public boolean equals(Object that) { 1150 if (!(that instanceof LargeInteger)) 1151 return false; 1152 LargeInteger li = (LargeInteger) that; 1153 return (_size == li._size) && (_isNegative == li._isNegative) 1154 && (compare(_words, li._words, _size) == 0); 1155 } 1156 1157 1162 public int hashCode() { 1163 long code = 0; 1164 for (int i = _size - 1; i >= 0; i--) { 1165 code = code * 31 + _words[i]; 1166 } 1167 return _isNegative ? -(int) code : (int) code; 1168 } 1169 1170 1180 public int toInt() { 1181 if (((_size > 1) || (_words[0] > Integer.MAX_VALUE)) 1182 && !this.equals(INT_MIN_VALUE)) 1183 throw new ArithmeticException (this 1184 + " cannot be represented as int"); 1185 return (int) longValue(); 1186 } 1187 1188 1198 public long toLong() { 1199 if ((_size > 1) && !this.equals(LONG_MIN_VALUE)) 1200 throw new ArithmeticException (this 1201 + " cannot be represented as long"); 1202 return longValue(); 1203 } 1204 1205 1216 public long longValue() { 1217 if (_size == 0) 1218 return 0; 1219 if (_size == 1) 1220 return _isNegative ? -_words[0] : _words[0]; 1221 return _isNegative ? -((_words[1] << 63) | _words[0]) 1223 : (_words[1] << 63) | _words[0]; 1224 } 1225 1226 1232 public double doubleValue() { 1233 if (_size == 0) 1234 return 0.0; 1235 if (_size == 1) 1236 return _isNegative ? -_words[0] : _words[0]; 1237 int bitLength = this.bitLength(); 1239 int pow2 = bitLength - 63; 1240 LargeInteger int63bits = this.shiftRight(pow2); 1241 double d = MathLib.toDoublePow2(int63bits._words[0], pow2); 1242 return _isNegative ? -d : d; 1243 1244 } 1245 1246 1255 public int compareTo(LargeInteger that) { 1256 if (_isNegative && !that._isNegative) 1258 return -1; 1259 if (!_isNegative && that._isNegative) 1260 return 1; 1261 if (_size > that._size) 1263 return _isNegative ? -1 : 1; 1264 if (that._size > _size) 1265 return _isNegative ? 1 : -1; 1266 return _isNegative ? compare(that._words, _words, _size) : compare( 1268 _words, that._words, _size); 1269 } 1270 1271 1277 public LargeInteger copy() { 1278 LargeInteger li = newInstance(_size); 1279 li._isNegative = _isNegative; 1280 li._size = _size; 1281 if (_size > 1) { 1282 System.arraycopy(_words, 0, li._words, 0, _size); 1283 } else { 1284 li._words[0] = _words[0]; } 1286 return li; 1287 } 1288 1289 1295 public LargeInteger sqrt() { 1296 if (this.isNegative()) 1297 throw new ArithmeticException ("Square root of negative integer"); 1298 int bitLength = this.bitLength(); 1299 PoolContext.enter(); 1300 try { 1301 LargeInteger k = this 1303 .times2pow(-((bitLength >> 1) + (bitLength & 1))); 1304 while (true) { 1305 LargeInteger newK = (k.plus(this.divide(k))).times2pow(-1); 1306 if (newK.equals(k)) 1307 return k.export(); 1308 k = newK; 1309 } 1310 } finally { 1311 PoolContext.exit(); 1312 } 1313 } 1314 1315 1319 private static LargeInteger newInstance(int nbrWords) { 1320 return (nbrWords <= 4) ? FACTORY_4.object() 1321 : newLargeInstance(nbrWords); 1322 } 1323 1324 private static LargeInteger newLargeInstance(int nbrWords) { 1325 if (nbrWords <= 6) 1326 return FACTORY_6.object(); 1327 if (nbrWords <= 10) 1328 return FACTORY_10.object(); 1329 if (nbrWords <= 18) 1330 return FACTORY_18.object(); 1331 if (nbrWords <= 34) 1332 return FACTORY_34.object(); 1333 if (nbrWords <= 67) 1334 return FACTORY_67.object(); 1335 if (nbrWords <= 132) 1336 return FACTORY_132.object(); 1337 if (nbrWords <= 262) 1338 return FACTORY_262.object(); 1339 if (nbrWords <= 522) 1340 return FACTORY_522.object(); 1341 if (nbrWords <= 1042) 1342 return FACTORY_1042.object(); 1343 return new LargeInteger(nbrWords); } 1345 1346 private static final Factory<LargeInteger> FACTORY_4 = new Factory<LargeInteger>() { 1347 @Override 1348 protected LargeInteger create() { 1349 return new LargeInteger(4); } 1351 }; 1352 1353 private static final Factory<LargeInteger> FACTORY_6 = new Factory<LargeInteger>() { 1354 @Override 1355 protected LargeInteger create() { 1356 return new LargeInteger(6); } 1358 }; 1359 1360 private static final Factory<LargeInteger> FACTORY_10 = new Factory<LargeInteger>() { 1361 @Override 1362 protected LargeInteger create() { 1363 return new LargeInteger(10); } 1365 }; 1366 1367 private static final Factory<LargeInteger> FACTORY_18 = new Factory<LargeInteger>() { 1368 @Override 1369 protected LargeInteger create() { 1370 return new LargeInteger(18); } 1372 }; 1373 1374 private static final Factory<LargeInteger> FACTORY_34 = new Factory<LargeInteger>() { 1375 @Override 1376 protected LargeInteger create() { 1377 return new LargeInteger(34); } 1379 }; 1380 1381 private static final Factory<LargeInteger> FACTORY_67 = new Factory<LargeInteger>() { 1382 @Override 1383 protected LargeInteger create() { 1384 return new LargeInteger(67); } 1386 }; 1387 1388 private static final Factory<LargeInteger> FACTORY_132 = new Factory<LargeInteger>() { 1389 @Override 1390 protected LargeInteger create() { 1391 return new LargeInteger(132); } 1393 }; 1394 1395 private static final Factory<LargeInteger> FACTORY_262 = new Factory<LargeInteger>() { 1396 @Override 1397 protected LargeInteger create() { 1398 return new LargeInteger(262); } 1400 }; 1401 1402 private static final Factory<LargeInteger> FACTORY_522 = new Factory<LargeInteger>() { 1403 @Override 1404 protected LargeInteger create() { 1405 return new LargeInteger(522); } 1407 }; 1408 1409 private static final Factory<LargeInteger> FACTORY_1042 = new Factory<LargeInteger>() { 1410 @Override 1411 protected LargeInteger create() { 1412 return new LargeInteger(1042); } 1414 }; 1415 1416 private static final long serialVersionUID = 1L; 1417 1418 1421 static final class Format extends TextFormat<LargeInteger> { 1422 1423 private static Format INSTANCE = new Format(); 1424 1425 Appendable format(LargeInteger li, int radix, Appendable out) { 1426 return null; 1427 } 1428 1429 LargeInteger parse(CharSequence csq, int radix, Cursor cursor) { 1430 return null; 1431 } 1432 1433 @Override 1434 public Appendable format(LargeInteger li, Appendable out) 1435 throws IOException { 1436 if (li.isNegative()) { 1437 out.append('-'); 1438 } 1439 LargeInteger tmp = li.copy(); 1440 write(tmp, out); 1441 return out; 1442 } 1443 1444 private void write(LargeInteger li, Appendable out) throws IOException { 1446 if ((li._size <= 1)) { TypeFormat.format(li._words[0], out); 1448 return; 1449 } 1450 int rem = (int) Calculus.divide(li._words, li._size, 1000000000, 1451 li._words); 1452 li._size = (li._words[li._size - 1] == 0L) ? li._size - 1 1453 : li._size; 1454 write(li, out); 1455 for (int i = MathLib.digitLength(rem); i < 9; i++) { 1456 out.append('0'); 1457 } 1458 TypeFormat.format(rem, out); 1459 } 1460 1461 @Override 1462 public LargeInteger parse(CharSequence csq, Cursor cursor) { 1463 final int end = cursor.getEndIndex(); 1464 boolean isNegative = cursor.at('-', csq); 1465 cursor.increment(isNegative || cursor.at('+', csq) ? 1 : 0); 1466 LargeInteger li = ZERO.copy(); 1467 while (true) { int start = cursor.getIndex(); 1469 cursor.setEndIndex(MathLib.min(start + 18, end)); 1470 long l = TypeFormat.parseLong(csq, 10, cursor); 1471 LargeInteger tmp = li.times10pow(cursor.getIndex() - start); 1472 li = tmp.plus(l); 1473 if (cursor.getIndex() == end) 1474 break; char c = csq.charAt(cursor.getIndex()); 1476 if ((c < '0') || (c > '9')) 1477 break; } 1479 cursor.setEndIndex(end); li._isNegative = isNegative && (li._size != 0); 1481 return li; 1482 } 1483 } 1484 1485 1488 private static final LargeInteger INT_MIN_VALUE = LargeInteger.ONE 1489 .shiftLeft(31).opposite().moveHeap(); 1490 1491 1494 private static final LargeInteger LONG_MIN_VALUE = LargeInteger.ONE 1495 .shiftLeft(63).opposite().moveHeap(); 1496 1497} | Popular Tags |