| 1 5 6 9 10 package java.math; 11 12 import java.util.Random ; 13 import java.io.*; 14 15 79 80 public class BigInteger extends Number implements Comparable <BigInteger > { 81 89 int signum; 90 91 100 int[] mag; 101 102 106 113 private int bitCount = -1; 114 115 122 private int bitLength = -1; 123 124 131 private int lowestSetBit = -2; 132 133 141 private int firstNonzeroByteNum = -2; 142 143 149 private int firstNonzeroIntNum = -2; 150 151 154 private final static long LONG_MASK = 0xffffffffL; 155 156 158 168 public BigInteger(byte[] val) { 169 if (val.length == 0) 170 throw new NumberFormatException ("Zero length BigInteger"); 171 172 if (val[0] < 0) { 173 mag = makePositive(val); 174 signum = -1; 175 } else { 176 mag = stripLeadingZeroBytes(val); 177 signum = (mag.length == 0 ? 0 : 1); 178 } 179 } 180 181 187 private BigInteger(int[] val) { 188 if (val.length == 0) 189 throw new NumberFormatException ("Zero length BigInteger"); 190 191 if (val[0] < 0) { 192 mag = makePositive(val); 193 signum = -1; 194 } else { 195 mag = trustedStripLeadingZeroInts(val); 196 signum = (mag.length == 0 ? 0 : 1); 197 } 198 } 199 200 216 public BigInteger(int signum, byte[] magnitude) { 217 this.mag = stripLeadingZeroBytes(magnitude); 218 219 if (signum < -1 || signum > 1) 220 throw(new NumberFormatException ("Invalid signum value")); 221 222 if (this.mag.length==0) { 223 this.signum = 0; 224 } else { 225 if (signum == 0) 226 throw(new NumberFormatException ("signum-magnitude mismatch")); 227 this.signum = signum; 228 } 229 } 230 231 237 private BigInteger(int signum, int[] magnitude) { 238 this.mag = stripLeadingZeroInts(magnitude); 239 240 if (signum < -1 || signum > 1) 241 throw(new NumberFormatException ("Invalid signum value")); 242 243 if (this.mag.length==0) { 244 this.signum = 0; 245 } else { 246 if (signum == 0) 247 throw(new NumberFormatException ("signum-magnitude mismatch")); 248 this.signum = signum; 249 } 250 } 251 252 268 public BigInteger(String val, int radix) { 269 int cursor = 0, numDigits; 270 int len = val.length(); 271 272 if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) 273 throw new NumberFormatException ("Radix out of range"); 274 if (val.length() == 0) 275 throw new NumberFormatException ("Zero length BigInteger"); 276 277 signum = 1; 279 int index = val.lastIndexOf("-"); 280 if (index != -1) { 281 if (index == 0) { 282 if (val.length() == 1) 283 throw new NumberFormatException ("Zero length BigInteger"); 284 signum = -1; 285 cursor = 1; 286 } else { 287 throw new NumberFormatException ("Illegal embedded minus sign"); 288 } 289 } 290 291 while (cursor < len && 293 Character.digit(val.charAt(cursor),radix) == 0) 294 cursor++; 295 if (cursor == len) { 296 signum = 0; 297 mag = ZERO.mag; 298 return; 299 } else { 300 numDigits = len - cursor; 301 } 302 303 int numBits = (int)(((numDigits * bitsPerDigit[radix]) >>> 10) + 1); 306 int numWords = (numBits + 31) /32; 307 mag = new int[numWords]; 308 309 int firstGroupLen = numDigits % digitsPerInt[radix]; 311 if (firstGroupLen == 0) 312 firstGroupLen = digitsPerInt[radix]; 313 String group = val.substring(cursor, cursor += firstGroupLen); 314 mag[mag.length - 1] = Integer.parseInt(group, radix); 315 if (mag[mag.length - 1] < 0) 316 throw new NumberFormatException ("Illegal digit"); 317 318 int superRadix = intRadix[radix]; 320 int groupVal = 0; 321 while (cursor < val.length()) { 322 group = val.substring(cursor, cursor += digitsPerInt[radix]); 323 groupVal = Integer.parseInt(group, radix); 324 if (groupVal < 0) 325 throw new NumberFormatException ("Illegal digit"); 326 destructiveMulAdd(mag, superRadix, groupVal); 327 } 328 mag = trustedStripLeadingZeroInts(mag); 330 } 331 332 BigInteger(char[] val) { 334 int cursor = 0, numDigits; 335 int len = val.length; 336 337 signum = 1; 339 if (val[0] == '-') { 340 if (len == 1) 341 throw new NumberFormatException ("Zero length BigInteger"); 342 signum = -1; 343 cursor = 1; 344 } 345 346 while (cursor < len && Character.digit(val[cursor], 10) == 0) 348 cursor++; 349 if (cursor == len) { 350 signum = 0; 351 mag = ZERO.mag; 352 return; 353 } else { 354 numDigits = len - cursor; 355 } 356 357 int numWords; 359 if (len < 10) { 360 numWords = 1; 361 } else { 362 int numBits = (int)(((numDigits * bitsPerDigit[10]) >>> 10) + 1); 363 numWords = (numBits + 31) /32; 364 } 365 mag = new int[numWords]; 366 367 int firstGroupLen = numDigits % digitsPerInt[10]; 369 if (firstGroupLen == 0) 370 firstGroupLen = digitsPerInt[10]; 371 mag[mag.length-1] = parseInt(val, cursor, cursor += firstGroupLen); 372 373 while (cursor < len) { 375 int groupVal = parseInt(val, cursor, cursor += digitsPerInt[10]); 376 destructiveMulAdd(mag, intRadix[10], groupVal); 377 } 378 mag = trustedStripLeadingZeroInts(mag); 379 } 380 381 private int parseInt(char[] source, int start, int end) { 385 int result = Character.digit(source[start++], 10); 386 if (result == -1) 387 throw new NumberFormatException (new String (source)); 388 389 for (int index = start; index<end; index++) { 390 int nextVal = Character.digit(source[index], 10); 391 if (nextVal == -1) 392 throw new NumberFormatException (new String (source)); 393 result = 10*result + nextVal; 394 } 395 396 return result; 397 } 398 399 private static long bitsPerDigit[] = { 0, 0, 402 1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672, 403 3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633, 404 4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210, 405 5253, 5295}; 406 407 private static void destructiveMulAdd(int[] x, int y, int z) { 409 long ylong = y & LONG_MASK; 411 long zlong = z & LONG_MASK; 412 int len = x.length; 413 414 long product = 0; 415 long carry = 0; 416 for (int i = len-1; i >= 0; i--) { 417 product = ylong * (x[i] & LONG_MASK) + carry; 418 x[i] = (int)product; 419 carry = product >>> 32; 420 } 421 422 long sum = (x[len-1] & LONG_MASK) + zlong; 424 x[len-1] = (int)sum; 425 carry = sum >>> 32; 426 for (int i = len-2; i >= 0; i--) { 427 sum = (x[i] & LONG_MASK) + carry; 428 x[i] = (int)sum; 429 carry = sum >>> 32; 430 } 431 } 432 433 446 public BigInteger(String val) { 447 this(val, 10); 448 } 449 450 463 public BigInteger(int numBits, Random rnd) { 464 this(1, randomBits(numBits, rnd)); 465 } 466 467 private static byte[] randomBits(int numBits, Random rnd) { 468 if (numBits < 0) 469 throw new IllegalArgumentException ("numBits must be non-negative"); 470 int numBytes = (numBits+7)/8; 471 byte[] randomBits = new byte[numBytes]; 472 473 if (numBytes > 0) { 475 rnd.nextBytes(randomBits); 476 int excessBits = 8*numBytes - numBits; 477 randomBits[0] &= (1 << (8-excessBits)) - 1; 478 } 479 return randomBits; 480 } 481 482 501 public BigInteger(int bitLength, int certainty, Random rnd) { 502 BigInteger prime; 503 504 if (bitLength < 2) 505 throw new ArithmeticException ("bitLength < 2"); 506 prime = (bitLength < 95 ? smallPrime(bitLength, certainty, rnd) 508 : largePrime(bitLength, certainty, rnd)); 509 signum = 1; 510 mag = prime.mag; 511 } 512 513 private static final int SMALL_PRIME_THRESHOLD = 95; 516 517 private static final int DEFAULT_PRIME_CERTAINTY = 100; 519 520 532 public static BigInteger probablePrime(int bitLength, Random rnd) { 533 if (bitLength < 2) 534 throw new ArithmeticException ("bitLength < 2"); 535 536 return (bitLength < SMALL_PRIME_THRESHOLD ? 538 smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) : 539 largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd)); 540 } 541 542 549 private static BigInteger smallPrime(int bitLength, int certainty, Random rnd) { 550 int magLen = (bitLength + 31) >>> 5; 551 int temp[] = new int[magLen]; 552 int highBit = 1 << ((bitLength+31) & 0x1f); int highMask = (highBit << 1) - 1; 555 while(true) { 556 for (int i=0; i<magLen; i++) 558 temp[i] = rnd.nextInt(); 559 temp[0] = (temp[0] & highMask) | highBit; if (bitLength > 2) 561 temp[magLen-1] |= 1; 563 BigInteger p = new BigInteger (temp, 1); 564 565 if (bitLength > 6) { 567 long r = p.remainder(SMALL_PRIME_PRODUCT).longValue(); 568 if ((r%3==0) || (r%5==0) || (r%7==0) || (r%11==0) || 569 (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) || 570 (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0)) 571 continue; } 573 574 if (bitLength < 4) 576 return p; 577 578 if (p.primeToCertainty(certainty)) 580 return p; 581 } 582 } 583 584 private static final BigInteger SMALL_PRIME_PRODUCT 585 = valueOf(3L*5*7*11*13*17*19*23*29*31*37*41); 586 587 593 private static BigInteger largePrime(int bitLength, int certainty, Random rnd) { 594 BigInteger p; 595 p = new BigInteger (bitLength, rnd).setBit(bitLength-1); 596 p.mag[p.mag.length-1] &= 0xfffffffe; 597 598 int searchLen = (bitLength / 20) * 64; 600 BitSieve searchSieve = new BitSieve (p, searchLen); 601 BigInteger candidate = searchSieve.retrieve(p, certainty); 602 603 while ((candidate == null) || (candidate.bitLength() != bitLength)) { 604 p = p.add(BigInteger.valueOf(2*searchLen)); 605 if (p.bitLength() != bitLength) 606 p = new BigInteger (bitLength, rnd).setBit(bitLength-1); 607 p.mag[p.mag.length-1] &= 0xfffffffe; 608 searchSieve = new BitSieve (p, searchLen); 609 candidate = searchSieve.retrieve(p, certainty); 610 } 611 return candidate; 612 } 613 614 626 public BigInteger nextProbablePrime() { 627 if (this.signum < 0) 628 throw new ArithmeticException ("start < 0: " + this); 629 630 if ((this.signum == 0) || this.equals(ONE)) 632 return TWO; 633 634 BigInteger result = this.add(ONE); 635 636 if (result.bitLength() < SMALL_PRIME_THRESHOLD) { 638 639 if (!result.testBit(0)) 641 result = result.add(ONE); 642 643 while(true) { 644 if (result.bitLength() > 6) { 646 long r = result.remainder(SMALL_PRIME_PRODUCT).longValue(); 647 if ((r%3==0) || (r%5==0) || (r%7==0) || (r%11==0) || 648 (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) || 649 (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0)) { 650 result = result.add(TWO); 651 continue; } 653 } 654 655 if (result.bitLength() < 4) 657 return result; 658 659 if (result.primeToCertainty(DEFAULT_PRIME_CERTAINTY)) 661 return result; 662 663 result = result.add(TWO); 664 } 665 } 666 667 if (result.testBit(0)) 669 result = result.subtract(ONE); 670 671 int searchLen = (result.bitLength() / 20) * 64; 673 674 while(true) { 675 BitSieve searchSieve = new BitSieve (result, searchLen); 676 BigInteger candidate = searchSieve.retrieve(result, 677 DEFAULT_PRIME_CERTAINTY); 678 if (candidate != null) 679 return candidate; 680 result = result.add(BigInteger.valueOf(2 * searchLen)); 681 } 682 } 683 684 698 boolean primeToCertainty(int certainty) { 699 int rounds = 0; 700 int n = (Math.min(certainty, Integer.MAX_VALUE-1)+1)/2; 701 702 int sizeInBits = this.bitLength(); 706 if (sizeInBits < 100) { 707 rounds = 50; 708 rounds = n < rounds ? n : rounds; 709 return passesMillerRabin(rounds); 710 } 711 712 if (sizeInBits < 256) { 713 rounds = 27; 714 } else if (sizeInBits < 512) { 715 rounds = 15; 716 } else if (sizeInBits < 768) { 717 rounds = 8; 718 } else if (sizeInBits < 1024) { 719 rounds = 4; 720 } else { 721 rounds = 2; 722 } 723 rounds = n < rounds ? n : rounds; 724 725 return passesMillerRabin(rounds) && passesLucasLehmer(); 726 } 727 728 734 private boolean passesLucasLehmer() { 735 BigInteger thisPlusOne = this.add(ONE); 736 737 int d = 5; 739 while (jacobiSymbol(d, this) != -1) { 740 d = (d<0) ? Math.abs(d)+2 : -(d+2); 742 } 743 744 BigInteger u = lucasLehmerSequence(d, thisPlusOne, this); 746 747 return u.mod(this).equals(ZERO); 749 } 750 751 755 private static int jacobiSymbol(int p, BigInteger n) { 756 if (p == 0) 757 return 0; 758 759 int j = 1; 761 int u = n.mag[n.mag.length-1]; 762 763 if (p < 0) { 765 p = -p; 766 int n8 = u & 7; 767 if ((n8 == 3) || (n8 == 7)) 768 j = -j; } 770 771 while ((p & 3) == 0) 773 p >>= 2; 774 if ((p & 1) == 0) { 775 p >>= 1; 776 if (((u ^ (u>>1)) & 2) != 0) 777 j = -j; } 779 if (p == 1) 780 return j; 781 if ((p & u & 2) != 0) j = -j; 784 u = n.mod(BigInteger.valueOf(p)).intValue(); 786 787 while (u != 0) { 789 while ((u & 3) == 0) 790 u >>= 2; 791 if ((u & 1) == 0) { 792 u >>= 1; 793 if (((p ^ (p>>1)) & 2) != 0) 794 j = -j; } 796 if (u == 1) 797 return j; 798 assert (u < p); 800 int t = u; u = p; p = t; 801 if ((u & p & 2) != 0) j = -j; 803 u %= p; 805 } 806 return 0; 807 } 808 809 private static BigInteger lucasLehmerSequence(int z, BigInteger k, BigInteger n) { 810 BigInteger d = BigInteger.valueOf(z); 811 BigInteger u = ONE; BigInteger u2; 812 BigInteger v = ONE; BigInteger v2; 813 814 for (int i=k.bitLength()-2; i>=0; i--) { 815 u2 = u.multiply(v).mod(n); 816 817 v2 = v.square().add(d.multiply(u.square())).mod(n); 818 if (v2.testBit(0)) { 819 v2 = n.subtract(v2); 820 v2.signum = - v2.signum; 821 } 822 v2 = v2.shiftRight(1); 823 824 u = u2; v = v2; 825 if (k.testBit(i)) { 826 u2 = u.add(v).mod(n); 827 if (u2.testBit(0)) { 828 u2 = n.subtract(u2); 829 u2.signum = - u2.signum; 830 } 831 u2 = u2.shiftRight(1); 832 833 v2 = v.add(d.multiply(u)).mod(n); 834 if (v2.testBit(0)) { 835 v2 = n.subtract(v2); 836 v2.signum = - v2.signum; 837 } 838 v2 = v2.shiftRight(1); 839 840 u = u2; v = v2; 841 } 842 } 843 return u; 844 } 845 846 |