1: 37: 38: 39: package ; 40: 41: import ; 42: 43: import ; 44: import ; 45: import ; 46: import ; 47: 48: 60: public class BigInteger extends Number implements Comparable<BigInteger> 61: { 62: 66: private transient int ival; 67: private transient int[] words; 68: 69: 70: private int bitCount = -1; 71: private int bitLength = -1; 72: private int firstNonzeroByteNum = -2; 73: private int lowestSetBit = -2; 74: private byte[] magnitude; 75: private int signum; 76: private static final long serialVersionUID = -8287574255936472291L; 77: 78: 79: 81: private static final int minFixNum = -100; 82: private static final int maxFixNum = 1024; 83: private static final int numFixNum = maxFixNum-minFixNum+1; 84: private static final BigInteger[] smallFixNums = new BigInteger[numFixNum]; 85: 86: static 87: { 88: for (int i = numFixNum; --i >= 0; ) 89: smallFixNums[i] = new BigInteger(i + minFixNum); 90: } 91: 92: 96: public static final BigInteger ZERO = smallFixNums[0 - minFixNum]; 97: 98: 102: public static final BigInteger ONE = smallFixNums[1 - minFixNum]; 103: 104: 108: public static final BigInteger TEN = smallFixNums[10 - minFixNum]; 109: 110: 111: private static final int FLOOR = 1; 112: private static final int CEILING = 2; 113: private static final int TRUNCATE = 3; 114: private static final int ROUND = 4; 115: 116: 119: private static final int[] primes = 120: { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 121: 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 122: 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 123: 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251 }; 124: 125: 126: private static final int[] k = 127: {100,150,200,250,300,350,400,500,600,800,1250, Integer.MAX_VALUE}; 128: private static final int[] t = 129: { 27, 18, 15, 12, 9, 8, 7, 6, 5, 4, 3, 2}; 130: 131: private BigInteger() 132: { 133: } 134: 135: 136: private BigInteger(int value) 137: { 138: ival = value; 139: } 140: 141: public BigInteger(String val, int radix) 142: { 143: BigInteger result = valueOf(val, radix); 144: this.ival = result.ival; 145: this.words = result.words; 146: } 147: 148: public BigInteger(String val) 149: { 150: this(val, 10); 151: } 152: 153: 154: public BigInteger(byte[] val) 155: { 156: if (val == null || val.length < 1) 157: throw new NumberFormatException(); 158: 159: words = byteArrayToIntArray(val, val[0] < 0 ? -1 : 0); 160: BigInteger result = make(words, words.length); 161: this.ival = result.ival; 162: this.words = result.words; 163: } 164: 165: public BigInteger(int signum, byte[] magnitude) 166: { 167: if (magnitude == null || signum > 1 || signum < -1) 168: throw new NumberFormatException(); 169: 170: if (signum == 0) 171: { 172: int i; 173: for (i = magnitude.length - 1; i >= 0 && magnitude[i] == 0; --i) 174: ; 175: if (i >= 0) 176: throw new NumberFormatException(); 177: return; 178: } 179: 180: 181: words = byteArrayToIntArray(magnitude, 0); 182: BigInteger result = make(words, words.length); 183: this.ival = result.ival; 184: this.words = result.words; 185: 186: if (signum < 0) 187: setNegative(); 188: } 189: 190: public BigInteger(int numBits, Random rnd) 191: { 192: if (numBits < 0) 193: throw new IllegalArgumentException(); 194: 195: init(numBits, rnd); 196: } 197: 198: private void init(int numBits, Random rnd) 199: { 200: int highbits = numBits & 31; 201: 202: int highBitByteCount = (highbits + 7) / 8; 203: 204: int discardedBitCount = highbits % 8; 205: if (discardedBitCount != 0) 206: discardedBitCount = 8 - discardedBitCount; 207: byte[] highBitBytes = new byte[highBitByteCount]; 208: if (highbits > 0) 209: { 210: rnd.nextBytes(highBitBytes); 211: highbits = (highBitBytes[highBitByteCount - 1] & 0xFF) >>> discardedBitCount; 212: for (int i = highBitByteCount - 2; i >= 0; i--) 213: highbits = (highbits << 8) | (highBitBytes[i] & 0xFF); 214: } 215: int nwords = numBits / 32; 216: 217: while (highbits == 0 && nwords > 0) 218: { 219: highbits = rnd.nextInt(); 220: --nwords; 221: } 222: if (nwords == 0 && highbits >= 0) 223: { 224: ival = highbits; 225: } 226: else 227: { 228: ival = highbits < 0 ? nwords + 2 : nwords + 1; 229: words = new int[ival]; 230: words[nwords] = highbits; 231: while (--nwords >= 0) 232: words[nwords] = rnd.nextInt(); 233: } 234: } 235: 236: public BigInteger(int bitLength, int certainty, Random rnd) 237: { 238: this(bitLength, rnd); 239: 240: 241: BigInteger result; 242: while (true) 243: { 244: 245: result = setBit(bitLength - 1); 246: this.ival = result.ival; 247: this.words = result.words; 248: if (isProbablePrime(certainty)) 249: return; 250: 251: init(bitLength, rnd); 252: } 253: } 254: 255: 264: public static BigInteger probablePrime(int bitLength, Random rnd) 265: { 266: if (bitLength < 2) 267: throw new ArithmeticException(); 268: 269: return new BigInteger(bitLength, 100, rnd); 270: } 271: 272: 273: public static BigInteger valueOf(long val) 274: { 275: if (val >= minFixNum && val <= maxFixNum) 276: return smallFixNums[(int) val - minFixNum]; 277: int i = (int) val; 278: if ((long) i == val) 279: return new BigInteger(i); 280: BigInteger result = alloc(2); 281: result.ival = 2; 282: result.words[0] = i; 283: result.words[1] = (int)(val >> 32); 284: return result; 285: } 286: 287: 289: private static BigInteger make(int[] words, int len) 290: { 291: if (words == null) 292: return valueOf(len); 293: len = BigInteger.wordsNeeded(words, len); 294: if (len <= 1) 295: return len == 0 ? ZERO : valueOf(words[0]); 296: BigInteger num = new BigInteger(); 297: num.words = words; 298: num.ival = len; 299: return num; 300: } 301: 302: 303: private static int[] byteArrayToIntArray(byte[] bytes, int sign) 304: { 305: 306: int[] words = new int[bytes.length/4 + 1]; 307: int nwords = words.length; 308: 309: 310: int bptr = 0; 311: int word = sign; 312: for (int i = bytes.length % 4; i > 0; --i, bptr++) 313: word = (word << 8) | (bytes[bptr] & 0xff); 314: words[--nwords] = word; 315: 316: 317: while (nwords > 0) 318: words[--nwords] = bytes[bptr++] << 24 | 319: (bytes[bptr++] & 0xff) << 16 | 320: (bytes[bptr++] & 0xff) << 8 | 321: (bytes[bptr++] & 0xff); 322: return words; 323: } 324: 325: 328: private static BigInteger alloc(int nwords) 329: { 330: BigInteger result = new BigInteger(); 331: if (nwords > 1) 332: result.words = new int[nwords]; 333: return result; 334: } 335: 336: 339: private void realloc(int nwords) 340: { 341: if (nwords == 0) 342: { 343: if (words != null) 344: { 345: if (ival > 0) 346: ival = words[0]; 347: words = null; 348: } 349: } 350: else if (words == null 351: || words.length < nwords 352: || words.length > nwords + 2) 353: { 354: int[] new_words = new int [nwords]; 355: if (words == null) 356: { 357: new_words[0] = ival; 358: ival = 1; 359: } 360: else 361: { 362: if (nwords < ival) 363: ival = nwords; 364: System.arraycopy(words, 0, new_words, 0, ival); 365: } 366: words = new_words; 367: } 368: } 369: 370: private boolean isNegative() 371: { 372: return (words == null ? ival : words[ival - 1]) < 0; 373: } 374: 375: public int signum() 376: { 377: if (ival == 0 && words == null) 378: return 0; 379: int top = words == null ? ival : words[ival-1]; 380: return top < 0 ? -1 : 1; 381: } 382: 383: private static int compareTo(BigInteger x, BigInteger y) 384: { 385: if (x.words == null && y.words == null) 386: return x.ival < y.ival ? -1 : x.ival > y.ival ? 1 : 0; 387: boolean x_negative = x.isNegative(); 388: boolean y_negative = y.isNegative(); 389: if (x_negative != y_negative) 390: return x_negative ? -1 : 1; 391: int x_len = x.words == null ? 1 : x.ival; 392: int y_len = y.words == null ? 1 : y.ival; 393: if (x_len != y_len) 394: return (x_len > y_len) != x_negative ? 1 : -1; 395: return MPN.cmp(x.words, y.words, x_len); 396: } 397: 398: 399: public int compareTo(BigInteger val) 400: { 401: return compareTo(this, val); 402: } 403: 404: public BigInteger min(BigInteger val) 405: { 406: return compareTo(this, val) < 0 ? this : val; 407: } 408: 409: public BigInteger max(BigInteger val) 410: { 411: return compareTo(this, val) > 0 ? this : val; 412: } 413: 414: private boolean isZero() 415: { 416: return words == null && ival == 0; 417: } 418: 419: private boolean isOne() 420: { 421: return words == null && ival == 1; 422: } 423: 424: 428: private static int wordsNeeded(int[] words, int len) 429: { 430: int i = len; 431: if (i > 0) 432: { 433: int word = words[--i]; 434: if (word == -1) 435: { 436: while (i > 0 && (word = words[i - 1]) < 0) 437: { 438: i--; 439: if (word != -1) break; 440: } 441: } 442: else 443: { 444: while (word == 0 && i > 0 && (word = words[i - 1]) >= 0) i--; 445: } 446: } 447: return i + 1; 448: } 449: 450: private BigInteger canonicalize() 451: { 452: if (words != null 453: && (ival = BigInteger.wordsNeeded(words, ival)) <= 1) 454: { 455: if (ival == 1) 456: ival = words[0]; 457: words = null; 458: } 459: if (words == null && ival >= minFixNum && ival <= maxFixNum) 460: return smallFixNums[ival - minFixNum]; 461: return this; 462: } 463: 464: 465: private static BigInteger add(int x, int y) 466: { 467: return valueOf((long) x + (long) y); 468: } 469: 470: 471: private static BigInteger add(BigInteger x, int y) 472: { 473: if (x.words == null) 474: return BigInteger.add(x.ival, y); 475: BigInteger result = new BigInteger(0); 476: result.setAdd(x, y); 477: return result.canonicalize(); 478: } 479: 480: 482: private void setAdd(BigInteger x, int y) 483: { 484: if (x.words == null) 485: { 486: set((long) x.ival + (long) y); 487: return; 488: } 489: int len = x.ival; 490: realloc(len + 1); 491: long carry = y; 492: for (int i = 0; i < len; i++) 493: { 494: carry += ((long) x.words[i] & 0xffffffffL); 495: words[i] = (int) carry; 496: carry >>= 32; 497: } 498: if (x.words[len - 1] < 0) 499: carry--; 500: words[len] = (int) carry; 501: ival = wordsNeeded(words, len + 1); 502: } 503: 504: 505: private void setAdd(int y) 506: { 507: setAdd(this, y); 508: } 509: 510: 511: private void set(long y) 512: { 513: int i = (int) y; 514: if ((long) i == y) 515: { 516: ival = i; 517: words = null; 518: } 519: else 520: { 521: realloc(2); 522: words[0] = i; 523: words[1] = (int) (y >> 32); 524: ival = 2; 525: } 526: } 527: 528: 530: private void set(int[] words, int length) 531: { 532: this.ival = length; 533: this.words = words; 534: } 535: 536: 537: private void set(BigInteger y) 538: { 539: if (y.words == null) 540: set(y.ival); 541: else if (this != y) 542: { 543: realloc(y.ival); 544: System.arraycopy(y.words, 0, words, 0, y.ival); 545: ival = y.ival; 546: } 547: } 548: 549: 550: private static BigInteger add(BigInteger x, BigInteger y, int k) 551: { 552: if (x.words == null && y.words == null) 553: return valueOf((long) k * (long) y.ival + (long) x.ival); 554: if (k != 1) 555: { 556: if (k == -1) 557: y = BigInteger.neg(y); 558: else 559: y = BigInteger.times(y, valueOf(k)); 560: } 561: if (x.words == null) 562: return BigInteger.add(y, x.ival); 563: if (y.words == null) 564: return BigInteger.add(x, y.ival); 565: 566: if (y.ival > x.ival) 567: { 568: BigInteger tmp = x; x = y; y = tmp; 569: } 570: BigInteger result = alloc(x.ival + 1); 571: int i = y.ival; 572: long carry = MPN.add_n(result.words, x.words, y.words, i); 573: long y_ext = y.words[i - 1] < 0 ? 0xffffffffL : 0; 574: for (; i < x.ival; i++) 575: { 576: carry += ((long) x.words[i] & 0xffffffffL) + y_ext; 577: result.words[i] = (int) carry; 578: carry >>>= 32; 579: } 580: if (x.words[i - 1] < 0) 581: y_ext--; 582: result.words[i] = (int) (carry + y_ext); 583: result.ival = i+1; 584: return result.canonicalize(); 585: } 586: 587: public BigInteger add(BigInteger val) 588: { 589: return add(this, val, 1); 590: } 591: 592: public BigInteger subtract(BigInteger val) 593: { 594: return add(this, val, -1); 595: } 596: 597: private static BigInteger times(BigInteger x, int y) 598: { 599: if (y == 0) 600: return ZERO; 601: if (y == 1) 602: return x; 603: int[] xwords = x.words; 604: int xlen = x.ival; 605: if (xwords == null) 606: return valueOf((long) xlen * (long) y); 607: boolean negative; 608: BigInteger result = BigInteger.alloc(xlen + 1); 609: if (xwords[xlen - 1] < 0) 610: { 611: negative = true; 612: negate(result.words, xwords, xlen); 613: xwords = result.words; 614: } 615: else 616: negative = false; 617: if (y < 0) 618: { 619: negative = !negative; 620: y = -y; 621: } 622: result.words[xlen] = MPN.mul_1(result.words, xwords, xlen, y); 623: result.ival = xlen + 1; 624: if (negative) 625: result.setNegative(); 626: return result.canonicalize(); 627: } 628: 629: private static BigInteger times(BigInteger x, BigInteger y) 630: { 631: if (y.words == null) 632: return times(x, y.ival); 633: if (x.words == null) 634: return times(y, x.ival); 635: boolean negative = false; 636: int[] xwords; 637: int[] ywords; 638: int xlen = x.ival; 639: int ylen = y.ival; 640: if (x.isNegative()) 641: { 642: negative = true; 643: xwords = new int[xlen]; 644: negate(xwords, x.words, xlen); 645: } 646: else 647: { 648: negative = false; 649: xwords = x.words; 650: } 651: if (y.isNegative()) 652: { 653: negative = !negative; 654: ywords = new int[ylen]; 655: negate(ywords, y.words, ylen); 656: } 657: else 658: ywords = y.words; 659: 660: if (xlen < ylen) 661: { 662: int[] twords = xwords; xwords = ywords; ywords = twords; 663: int tlen = xlen; xlen = ylen; ylen = tlen; 664: } 665: BigInteger result = BigInteger.alloc(xlen+ylen); 666: MPN.mul(result.words, xwords, xlen, ywords, ylen); 667: result.ival = xlen+ylen; 668: if (negative) 669: result.setNegative(); 670: return result.canonicalize(); 671: } 672: 673: public BigInteger multiply(BigInteger y) 674: { 675: return times(this, y); 676: } 677: 678: private static void divide(long x, long y, 679: BigInteger quotient, BigInteger remainder, 680: int rounding_mode) 681: { 682: boolean xNegative, yNegative; 683: if (x < 0) 684: { 685: xNegative = true; 686: if (x == Long.MIN_VALUE) 687: { 688: divide(valueOf(x), valueOf(y), 689: quotient, remainder, rounding_mode); 690: return; 691: } 692: x = -x; 693: } 694: else 695: xNegative = false; 696: 697: if (y < 0) 698: { 699: yNegative = true; 700: if (y == Long.MIN_VALUE) 701: { 702: if (rounding_mode == TRUNCATE) 703: { 704: if (quotient != null) 705: quotient.set(0); 706: if (remainder != null) 707: remainder.set(x); 708: } 709: else 710: divide(valueOf(x), valueOf(y), 711: quotient, remainder, rounding_mode); 712: return; 713: } 714: y = -y; 715: } 716: else 717: yNegative = false; 718: 719: long q = x / y; 720: long r = x % y; 721: boolean qNegative = xNegative ^ yNegative; 722: 723: boolean add_one = false; 724: if (r != 0) 725: { 726: switch (rounding_mode) 727: { 728: case TRUNCATE: 729: break; 730: case CEILING: 731: case FLOOR: 732: if (qNegative == (rounding_mode == FLOOR)) 733: add_one = true; 734: break; 735: case ROUND: 736: add_one = r > ((y - (q & 1)) >> 1); 737: break; 738: } 739: } 740: if (quotient != null) 741: { 742: if (add_one) 743: q++; 744: if (qNegative) 745: q = -q; 746: quotient.set(q); 747: } 748: if (remainder != null) 749: { 750: 751: if (add_one) 752: { 753: 754: r = y - r; 755: 756: 757: xNegative = ! xNegative; 758: } 759: else 760: { 761: 762: 763: } 764: if (xNegative) 765: r = -r; 766: remainder.set(r); 767: } 768: } 769: 770: 778: private static void divide(BigInteger x, BigInteger y, 779: BigInteger quotient, BigInteger remainder, 780: int rounding_mode) 781: { 782: if ((x.words == null || x.ival <= 2) 783: && (y.words == null || y.ival <= 2)) 784: { 785: long x_l = x.longValue(); 786: long y_l = y.longValue(); 787: if (x_l != Long.MIN_VALUE && y_l != Long.MIN_VALUE) 788: { 789: divide(x_l, y_l, quotient, remainder, rounding_mode); 790: return; 791: } 792: } 793: 794: boolean xNegative = x.isNegative(); 795: boolean yNegative = y.isNegative(); 796: boolean qNegative = xNegative ^ yNegative; 797: 798: int ylen = y.words == null ? 1 : y.ival; 799: int[] ywords = new int[ylen]; 800: y.getAbsolute(ywords); 801: while (ylen > 1 && ywords[ylen - 1] == 0) ylen--; 802: 803: int xlen = x.words == null ? 1 : x.ival; 804: int[] xwords = new int[xlen+2]; 805: x.getAbsolute(xwords); 806: while (xlen > 1 && xwords[xlen-1] == 0) xlen--; 807: 808: int qlen, rlen; 809: 810: int cmpval = MPN.cmp(xwords, xlen, ywords, ylen); 811: if (cmpval < 0) 812: { 813: int[] rwords = xwords; xwords = ywords; ywords = rwords; 814: rlen = xlen; qlen = 1; xwords[0] = 0; 815: } 816: else if (cmpval == 0) 817: { 818: xwords[0] = 1; qlen = 1; 819: ywords[0] = 0; rlen = 1; 820: } 821: else if (ylen == 1) 822: { 823: qlen = xlen; 824: 825: 826: 827: 828: if (ywords[0] == 1 && xwords[xlen-1] < 0) 829: qlen++; 830: rlen = 1; 831: ywords[0] = MPN.divmod_1(xwords, xwords, xlen, ywords[0]); 832: } 833: else 834: { 835: 836: 837: 838: 839: int nshift = MPN.count_leading_zeros(ywords[ylen - 1]); 840: if (nshift != 0) 841: { 842: 843: 844: MPN.lshift(ywords, 0, ywords, ylen, nshift); 845: 846: 847: 848: int x_high = MPN.lshift(xwords, 0, xwords, xlen, nshift); 849: xwords[xlen++] = x_high; 850: } 851: 852: if (xlen == ylen) 853: xwords[xlen++] = 0; 854: MPN.divide(xwords, xlen, ywords, ylen); 855: rlen = ylen; 856: MPN.rshift0 (ywords, xwords, 0, rlen, nshift); 857: 858: qlen = xlen + 1 - ylen; 859: if (quotient != null) 860: { 861: for (int i = 0; i < qlen; i++) 862: xwords[i] = xwords[i+ylen]; 863: } 864: } 865: 866: if (ywords[rlen-1] < 0) 867: { 868: ywords[rlen] = 0; 869: rlen++; 870: } 871: 872: 873: 874: boolean add_one = false; 875: if (rlen > 1 || ywords[0] != 0) 876: { 877: switch (rounding_mode) 878: { 879: case TRUNCATE: 880: break; 881: case CEILING: 882: case FLOOR: 883: if (qNegative == (rounding_mode == FLOOR)) 884: add_one = true; 885: break; 886: case ROUND: 887: 888: BigInteger tmp = remainder == null ? new BigInteger() : remainder; 889: tmp.set(ywords, rlen); 890: tmp = shift(tmp, 1); 891: if (yNegative) 892: tmp.setNegative(); 893: int cmp = compareTo(tmp, y); 894: 895: if (yNegative) 896: cmp = -cmp; 897: add_one = (cmp == 1) || (cmp == 0 && (xwords[0]&1) != 0); 898: } 899: } 900: if (quotient != null) 901: { 902: quotient.set(xwords, qlen); 903: if (qNegative) 904: { 905: if (add_one) 906: quotient.setInvert(); 907: else 908: quotient.setNegative(); 909: } 910: else if (add_one) 911: quotient.setAdd(1); 912: } 913: if (remainder != null) 914: { 915: 916: remainder.set(ywords, rlen); 917: if (add_one) 918: { 919: 920: 921: BigInteger tmp; 922: if (y.words == null) 923: { 924: tmp = remainder; 925: tmp.set(yNegative ? ywords[0] + y.ival : ywords[0] - y.ival); 926: } 927: else 928: tmp = BigInteger.add(remainder, y, yNegative ? 1 : -1); 929: 930: 931: 932: 933: if (xNegative) 934: remainder.setNegative(tmp); 935: else 936: remainder.set(tmp); 937: } 938: else 939: { 940: 941: 942: if (xNegative) 943: remainder.setNegative(); 944: } 945: } 946: } 947: 948: public BigInteger divide(BigInteger val) 949: { 950: if (val.isZero()) 951: throw new ArithmeticException("divisor is zero"); 952: 953: BigInteger quot = new BigInteger(); 954: divide(this, val, quot, null, TRUNCATE); 955: return quot.canonicalize(); 956: } 957: 958: public BigInteger remainder(BigInteger val) 959: { 960: if (val.isZero()) 961: throw new ArithmeticException("divisor is zero"); 962: 963: BigInteger rem = new BigInteger(); 964: divide(this, val, null, rem, TRUNCATE); 965: return rem.canonicalize(); 966: } 967: 968: public BigInteger[] divideAndRemainder(BigInteger val) 969: { 970: if (val.isZero()) 971: throw new ArithmeticException("divisor is zero"); 972: 973: BigInteger[] result = new BigInteger[2]; 974: result[0] = new BigInteger(); 975: result[1] = new BigInteger(); 976: divide(this, val, result[0], result[1], TRUNCATE); 977: result[0].canonicalize(); 978: result[1].canonicalize(); 979: return result; 980: } 981: 982: public BigInteger mod(BigInteger m) 983: { 984: if (m.isNegative() || m.isZero()) 985: throw new ArithmeticException("non-positive modulus"); 986: 987: BigInteger rem = new BigInteger(); 988: divide(this, m, null, rem, FLOOR); 989: return rem.canonicalize(); 990: } 991: 992: 995: public BigInteger pow(int exponent) 996: { 997: if (exponent <= 0) 998: { 999: if (exponent == 0) 1000: return ONE; 1001: throw new ArithmeticException("negative exponent"); 1002: } 1003: if (isZero()) 1004: return this; 1005: int plen = words == null ? 1 : ival; 1006: int blen = ((bitLength() * exponent) >> 5) + 2 * plen; 1007: boolean negative = isNegative() && (exponent & 1) != 0; 1008: int[] pow2 = new int [blen]; 1009: int[] rwords = new int [blen]; 1010: int[] work = new int [blen]; 1011: getAbsolute(pow2); 1012: int rlen = 1; 1013: rwords[0] = 1; 1014: for (;;) 1015: { 1016: 1017: 1018: if ((exponent & 1) != 0) 1019: { 1020: MPN.mul(work, pow2, plen, rwords, rlen); 1021: int[] temp = work; work = rwords; rwords = temp; 1022: rlen += plen; 1023: while (rwords[rlen - 1] == 0) rlen--; 1024: } 1025: exponent >>= 1; 1026: if (exponent == 0) 1027: break; 1028: 1029: MPN.mul(work, pow2, plen, pow2, plen); 1030: int[] temp = work; work = pow2; pow2 = temp; 1031: plen *= 2; 1032: while (pow2[plen - 1] == 0) plen--; 1033: } 1034: if (rwords[rlen - 1] < 0) 1035: rlen++; 1036: if (negative) 1037: negate(rwords, rwords, rlen); 1038: return BigInteger.make(rwords, rlen); 1039: } 1040: 1041: private static int[] euclidInv(int a, int b, int prevDiv) 1042: { 1043: if (b == 0) 1044: throw new ArithmeticException("not invertible"); 1045: 1046: if (b == 1) 1047: 1048: 1049: return new int[] { -prevDiv, 1 }; 1050: 1051: int[] xy = euclidInv(b, a % b, a / b); 1052: a = xy[0]; 1053: xy[0] = a * -prevDiv + xy[1]; 1054: xy[1] = a; 1055: return xy; 1056: } 1057: 1058: private static void euclidInv(BigInteger a, BigInteger b, 1059: BigInteger prevDiv, BigInteger[] xy) 1060: { 1061: if (b.isZero()) 1062: throw new ArithmeticException("not invertible"); 1063: 1064: if (b.isOne()) 1065: { 1066: 1067: 1068: xy[0] = neg(prevDiv); 1069: xy[1] = ONE; 1070: return; 1071: } 1072: 1073: 1074: 1075: 1076: if (a.words == null) 1077: { 1078: int[] xyInt = euclidInv(b.ival, a.ival % b.ival, a.ival / b.ival); 1079: xy[0] = new BigInteger(xyInt[0]); 1080: xy[1] = new BigInteger(xyInt[1]); 1081: } 1082: else 1083: { 1084: BigInteger rem = new BigInteger(); 1085: BigInteger quot = new BigInteger(); 1086: divide(a, b, quot, rem, FLOOR); 1087: 1088: rem.canonicalize(); 1089: quot.canonicalize(); 1090: euclidInv(b, rem, quot, xy); 1091: } 1092: 1093: BigInteger t = xy[0]; 1094: xy[0] = add(xy[1], times(t, prevDiv), -1); 1095: xy[1] = t; 1096: } 1097: 1098: public BigInteger modInverse(BigInteger y) 1099: { 1100: if (y.isNegative() || y.isZero()) 1101: throw new ArithmeticException("non-positive modulo"); 1102: 1103: 1104: if (y.isOne()) 1105: return ZERO; 1106: if (isOne()) 1107: return ONE; 1108: 1109: 1110: 1111: 1112: 1113: BigInteger result = new BigInteger(); 1114: boolean swapped = false; 1115: 1116: if (y.words == null) 1117: { 1118: 1119: 1120: 1121: 1122: 1123: 1124: int xval = (words != null || isNegative()) ? mod(y).ival : ival; 1125: int yval = y.ival; 1126: 1127: 1128: if (yval > xval) 1129: { 1130: int tmp = xval; xval = yval; yval = tmp; 1131: swapped = true; 1132: } 1133: 1134: 1135: 1136: result.ival = 1137: euclidInv(yval, xval % yval, xval / yval)[swapped ? 0 : 1]; 1138: 1139: 1140: 1141: if (result.ival < 0) 1142: result.ival += y.ival; 1143: } 1144: else 1145: { 1146: 1147: BigInteger x = isNegative() ? this.mod(y) : this; 1148: 1149: 1150: if (x.compareTo(y) < 0) 1151: { 1152: result = x; x = y; y = result; 1153: swapped = true; 1154: } 1155: 1156: 1157: BigInteger rem = new BigInteger(); 1158: BigInteger quot = new BigInteger(); 1159: divide(x, y, quot, rem, FLOOR); 1160: 1161: rem.canonicalize(); 1162: quot.canonicalize(); 1163: BigInteger[] xy = new BigInteger[2]; 1164: euclidInv(y, rem, quot, xy); 1165: result = swapped ? xy[0] : xy[1]; 1166: 1167: 1168: 1169: if (result.isNegative()) 1170: result = add(result, swapped ? x : y, 1); 1171: } 1172: 1173: return result; 1174: } 1175: 1176: public BigInteger modPow(BigInteger exponent, BigInteger m) 1177: { 1178: if (m.isNegative() || m.isZero()) 1179: throw new ArithmeticException("non-positive modulo"); 1180: 1181: if (exponent.isNegative()) 1182: return modInverse(m).modPow(exponent.negate(), m); 1183: if (exponent.isOne()) 1184: return mod(m); 1185: 1186: 1187: 1188: 1189: 1190: 1191: 1192: 1193: BigInteger s = ONE; 1194: BigInteger t = this; 1195: BigInteger u = exponent; 1196: 1197: while (!u.isZero()) 1198: { 1199: if (u.and(ONE).isOne()) 1200: s = times(s, t).mod(m); 1201: u = u.shiftRight(1); 1202: t = times(t, t).mod(m); 1203: } 1204: 1205: return s; 1206: } 1207: 1208: 1209: private static int gcd(int a, int b) 1210: { 1211: 1212: int tmp; 1213: if (b > a) 1214: { 1215: tmp = a; a = b; b = tmp; 1216: } 1217: for(;;) 1218: { 1219: if (b == 0) 1220: return a; 1221: if (b == 1) 1222: return b; 1223: tmp = b; 1224: b = a % b; 1225: a = tmp; 1226: } 1227: } 1228: 1229: public BigInteger gcd(BigInteger y) 1230: { 1231: int xval = ival; 1232: int yval = y.ival; 1233: if (words == null) 1234: { 1235: if (xval == 0) 1236: return abs(y); 1237: if (y.words == null 1238: && xval != Integer.MIN_VALUE && yval != Integer.MIN_VALUE) 1239: { 1240: if (xval < 0) 1241: xval = -xval; 1242: if (yval < 0) 1243: yval = -yval; 1244: return valueOf(gcd(xval, yval)); 1245: } 1246: xval = 1; 1247: } 1248: if (y.words == null) 1249: { 1250: if (yval == 0) 1251: return abs(this); 1252: yval = 1; 1253: } 1254: int len = (xval > yval ? xval : yval) + 1; 1255: int[] xwords = new int[len]; 1256: int[] ywords = new int[len]; 1257: getAbsolute(xwords); 1258: y.getAbsolute(ywords); 1259: len = MPN.gcd(xwords, ywords, len); 1260: BigInteger result = new BigInteger(0); 1261: result.ival = len; 1262: result.words = xwords; 1263: return result.canonicalize(); 1264: } 1265: 1266: 1279: public boolean isProbablePrime(int certainty) 1280: { 1281: if (certainty < 1) 1282: return true; 1283: 1284: 1294: 1295: 1296: BigInteger rem = new BigInteger(); 1297: int i; 1298: for (i = 0; i < primes.length; i++) 1299: { 1300: if (words == null && ival == primes[i]) 1301: return true; 1302: 1303: divide(this, smallFixNums[primes[i] - minFixNum], null, rem, TRUNCATE); 1304: if (rem.canonicalize().isZero()) 1305: return false; 1306: } 1307: 1308: 1309: 1310: 1311: 1312: BigInteger pMinus1 = add(this, -1); 1313: int b = pMinus1.getLowestSetBit(); 1314: 1315: 1316: BigInteger m = pMinus1.divide(valueOf(2L << b - 1)); 1317: 1318: 1319: 1320: 1321: 1322: 1323: int bits = this.bitLength(); 1324: for (i = 0; i < k.length; i++) 1325: if (bits <= k[i]) 1326: break; 1327: int trials = t[i]; 1328: if (certainty > 80) 1329: trials *= 2; 1330: BigInteger z; 1331: for (int t = 0; t < trials; t++) 1332: { 1333: 1334: 1335: 1336: 1337: z = smallFixNums[primes[t] - minFixNum].modPow(m, this); 1338: if (z.isOne() || z.equals(pMinus1)) 1339: continue; 1340: 1341: for (i = 0; i < b; ) 1342: { 1343: if (z.isOne()) 1344: return false; 1345: i++; 1346: if (z.equals(pMinus1)) 1347: break; 1348: 1349: z = z.modPow(valueOf(2), this); 1350: } 1351: 1352: if (i == b && !z.equals(pMinus1)) 1353: return false; 1354: } 1355: return true; 1356: } 1357: 1358: private void setInvert() 1359: { 1360: if (words == null) 1361: ival = ~ival; 1362: else 1363: { 1364: for (int i = ival; --i >= 0; ) 1365: words[i] = ~words[i]; 1366: } 1367: } 1368: 1369: private void setShiftLeft(BigInteger x, int count) 1370: { 1371: int[] xwords; 1372: int xlen; 1373: if (x.words == null) 1374: { 1375: if (count < 32) 1376: { 1377: set((long) x.ival << count); 1378: return; 1379: } 1380: xwords = new int[1]; 1381: xwords[0] = x.ival; 1382: xlen = 1; 1383: } 1384: else 1385: { 1386: xwords = x.words; 1387: xlen = x.ival; 1388: } 1389: int word_count = count >> 5; 1390: count &= 31; 1391: int new_len = xlen + word_count; 1392: if (count == 0) 1393: { 1394: realloc(new_len); 1395: for (int i = xlen; --i >= 0; ) 1396: words[i+word_count] = xwords[i]; 1397: } 1398: else 1399: { 1400: new_len++; 1401: realloc(new_len); 1402: int shift_out = MPN.lshift(words, word_count, xwords, xlen, count); 1403: count = 32 - count; 1404: words[new_len-1] = (shift_out << count) >> count; 1405: } 1406: ival = new_len; 1407: for (int i = word_count; --i >= 0; ) 1408: words[i] = 0; 1409: } 1410: 1411: private void setShiftRight(BigInteger x, int count) 1412: { 1413: if (x.words == null) 1414: set(count < 32 ? x.ival >> count : x.ival < 0 ? -1 : 0); 1415: else if (count == 0) 1416: set(x); 1417: else 1418: { 1419: boolean neg = x.isNegative(); 1420: int word_count = count >> 5; 1421: count &= 31; 1422: int d_len = x.ival - word_count; 1423: if (d_len <= 0) 1424: set(neg ? -1 : 0); 1425: else 1426: { 1427: if (words == null || words.length < d_len) 1428: realloc(d_len); 1429: MPN.rshift0 (words, x.words, word_count, d_len, count); 1430: ival = d_len; 1431: if (neg) 1432: words[d_len-1] |= -2 << (31 - count); 1433: } 1434: } 1435: } 1436: 1437: private void setShift(BigInteger x, int count) 1438: { 1439: if (count > 0) 1440: setShiftLeft(x, count); 1441: else 1442: setShiftRight(x, -count); 1443: } 1444: 1445: private static BigInteger shift(BigInteger x, int count) 1446: { 1447: if (x.words == null) 1448: { 1449: if (count <= 0) 1450: return valueOf(count > -32 ? x.ival >> (-count) : x.ival < 0 ? -1 : 0); 1451: if (count < 32) 1452: return valueOf((long) x.ival << count); 1453: } 1454: if (count == 0) 1455: return x; 1456: BigInteger result = new BigInteger(0); 1457: result.setShift(x, count); 1458: return result.canonicalize(); 1459: } 1460: 1461: public BigInteger shiftLeft(int n) 1462: { 1463: return shift(this, n); 1464: } 1465: 1466: public BigInteger shiftRight(int n) 1467: { 1468: return shift(this, -n); 1469: } 1470: 1471: private void format(int radix, StringBuffer buffer) 1472: { 1473: if (words == null) 1474: buffer.append(Integer.toString(ival, radix)); 1475: else if (ival <= 2) 1476: buffer.append(Long.toString(longValue(), radix)); 1477: else 1478: { 1479: boolean neg = isNegative(); 1480: int[] work; 1481: if (neg || radix != 16) 1482: { 1483: work = new int[ival]; 1484: getAbsolute(work); 1485: } 1486: else 1487: work = words; 1488: int len = ival; 1489: 1490: if (radix == 16) 1491: { 1492: if (neg) 1493: buffer.append('-'); 1494: int buf_start = buffer.length(); 1495: for (int i = len; --i >= 0; ) 1496: { 1497: int word = work[i]; 1498: for (int j = 8; --j >= 0; ) 1499: { 1500: int hex_digit = (word >> (4 * j)) & 0xF; 1501: 1502: if (hex_digit > 0 || buffer.length() > buf_start) 1503: buffer.append(Character.forDigit(hex_digit, 16)); 1504: } 1505: } 1506: } 1507: else 1508: { 1509: int i = buffer.length(); 1510: for (;;) 1511: { 1512: int digit = MPN.divmod_1(work, work, len, radix); 1513: buffer.append(Character.forDigit(digit, radix)); 1514: while (len > 0 && work[len-1] == 0) len--; 1515: if (len == 0) 1516: break; 1517: } 1518: if (neg) 1519: buffer.append('-'); 1520: 1521: int j = buffer.length() - 1; 1522: while (i < j) 1523: { 1524: char tmp = buffer.charAt(i); 1525: buffer.setCharAt(i, buffer.charAt(j)); 1526: buffer.setCharAt(j, tmp); 1527: i++; j--; 1528: } 1529: } 1530: } 1531: } 1532: 1533: public String toString() 1534: { 1535: return toString(10); 1536: } 1537: 1538: public String toString(int radix) 1539: { 1540: if (words == null) 1541: return Integer.toString(ival, radix); 1542: if (ival <= 2) 1543: return Long.toString(longValue(), radix); 1544: int buf_size = ival * (MPN.chars_per_word(radix) + 1); 1545: StringBuffer buffer = new StringBuffer(buf_size); 1546: format(radix, buffer); 1547: return buffer.toString(); 1548: } 1549: 1550: public int intValue() 1551: { 1552: if (words == null) 1553: return ival; 1554: return words[0]; 1555: } 1556: 1557: public long longValue() 1558: { 1559: if (words == null) 1560: return ival; 1561: if (ival == 1) 1562: return words[0]; 1563: return ((long)words[1] << 32) + ((long)words[0] & 0xffffffffL); 1564: } 1565: 1566: public int hashCode() 1567: { 1568: 1569: return words == null ? ival : (words[0] + words[ival - 1]); 1570: } 1571: 1572: 1573: private static boolean equals(BigInteger x, BigInteger y) 1574: { 1575: if (x.words == null && y.words == null) 1576: return x.ival == y.ival; 1577: if (x.words == null || y.words == null || x.ival != y.ival) 1578: return false; 1579: for (int i = x.ival; --i >= 0; ) 1580: { 1581: if (x.words[i] != y.words[i]) 1582: return false; 1583: } 1584: return true; 1585: } 1586: 1587: 1588: public boolean equals(Object obj) 1589: { 1590: if (! (obj instanceof BigInteger)) 1591: return false; 1592: return equals(this, (BigInteger) obj); 1593: } 1594: 1595: private static BigInteger valueOf(String s, int radix) 1596: throws NumberFormatException 1597: { 1598: int len = s.length(); 1599: 1600: 1601: if (len <= 15 && radix <= 16) 1602: return valueOf(Long.parseLong(s, radix)); 1603: 1604: int i, digit; 1605: boolean negative; 1606: byte[] bytes; 1607: char ch = s.charAt(0); 1608: if (ch == '-') 1609: { 1610: negative = true; 1611: i = 1; 1612: bytes = new byte[len - 1]; 1613: } 1614: else 1615: { 1616: negative = false; 1617: i = 0; 1618: bytes = new byte[len]; 1619: } 1620: int byte_len = 0; 1621: for ( ; i < len; i++) 1622: { 1623: ch = s.charAt(i); 1624: digit = Character.digit(ch, radix); 1625: if (digit < 0) 1626: throw new NumberFormatException(); 1627: bytes[byte_len++] = (byte) digit; 1628: } 1629: return valueOf(bytes, byte_len, negative, radix); 1630: } 1631: 1632: private static BigInteger valueOf(byte[] digits, int byte_len, 1633: boolean negative, int radix) 1634: { 1635: int chars_per_word = MPN.chars_per_word(radix); 1636: int[] words = new int[byte_len / chars_per_word + 1]; 1637: int size = MPN.set_str(words, digits, byte_len, radix); 1638: if (size == 0) 1639: return ZERO; 1640: if (words[size-1] < 0) 1641: words[size++] = 0; 1642: if (negative) 1643: negate(words, words, size); 1644: return make(words, size); 1645: } 1646: 1647: public double doubleValue() 1648: { 1649: if (words == null) 1650: return (double) ival; 1651: if (ival <= 2) 1652: return (double) longValue(); 1653: if (isNegative()) 1654: return neg(this).roundToDouble(0, true, false); 1655: return roundToDouble(0, false, false); 1656: } 1657: 1658: public float floatValue() 1659: { 1660: return (float) doubleValue(); 1661: } 1662: 1663: 1665: private boolean checkBits(int n) 1666: { 1667: if (n <= 0) 1668: return false; 1669: if (words == null) 1670: return n > 31 || ((ival & ((1 << n) - 1)) != 0); 1671: int i; 1672: for (i = 0; i < (n >> 5) ; i++) 1673: if (words[i] != 0) 1674: return true; 1675: return (n & 31) != 0 && (words[i] & ((1 << (n & 31)) - 1)) != 0; 1676: } 1677: 1678: 1686: private double roundToDouble(int exp, boolean neg, boolean remainder) 1687: { 1688: 1689: int il = bitLength(); 1690: 1691: 1692: 1693: exp += il - 1; 1694: 1695: 1696: 1697: 1698: 1699: if (exp < -1075) 1700: return neg ? -0.0 : 0.0; 1701: 1702: 1703: if (exp > 1023) 1704: return neg ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; 1705: 1706: 1707: 1708: int ml = (exp >= -1022 ? 53 : 53 + exp + 1022); 1709: 1710: 1711: long m; 1712: int excess_bits = il - (ml + 1); 1713: if (excess_bits > 0) 1714: m = ((words == null) ? ival >> excess_bits 1715: : MPN.rshift_long(words, ival, excess_bits)); 1716: else 1717: m = longValue() << (- excess_bits); 1718: 1719: 1720: 1721: if (exp == 1023 && ((m >> 1) == (1L << 53) - 1)) 1722: { 1723: if (remainder || checkBits(il - ml)) 1724: return neg ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; 1725: else 1726: return neg ? - Double.MAX_VALUE : Double.MAX_VALUE; 1727: } 1728: 1729: 1730: 1731: if ((m & 1) == 1 1732: && ((m & 2) == 2 || remainder || checkBits(excess_bits))) 1733: { 1734: m += 2; 1735: 1736: if ((m & (1L << 54)) != 0) 1737: { 1738: exp++; 1739: 1740: m >>= 1; 1741: } 1742: 1743: 1744: else if (ml == 52 && (m & (1L << 53)) != 0) 1745: exp++; 1746: } 1747: 1748: 1749: m >>= 1; 1750: 1751: long bits_sign = neg ? (1L << 63) : 0; 1752: exp += 1023; 1753: long bits_exp = (exp <= 0) ? 0 : ((long)exp) << 52; 1754: long bits_mant = m & ~(1L << 52); 1755: return Double.longBitsToDouble(bits_sign | bits_exp | bits_mant); 1756: } 1757: 1758: 1762: private void getAbsolute(int[] words) 1763: { 1764: int len; 1765: if (this.words == null) 1766: { 1767: len = 1; 1768: words[0] = this.ival; 1769: } 1770: else 1771: { 1772: len = this.ival; 1773: for (int i = len; --i >= 0; ) 1774: words[i] = this.words[i]; 1775: } 1776: if (words[len - 1] < 0) 1777: negate(words, words, len); 1778: for (int i = words.length; --i > len; ) 1779: words[i] = 0; 1780: } 1781: 1782: 1785: private static boolean negate(int[] dest, int[] src, int len) 1786: { 1787: long carry = 1; 1788: boolean negative = src[len-1] < 0; 1789: for (int i = 0; i < len; i++) 1790: { 1791: carry += ((long) (~src[i]) & 0xffffffffL); 1792: dest[i] = (int) carry; 1793: carry >>= 32; 1794: } 1795: return (negative && dest[len-1] < 0); 1796: } 1797: 1798: 1800: private void setNegative(BigInteger x) 1801: { 1802: int len = x.ival; 1803: if (x.words == null) 1804: { 1805: if (len == Integer.MIN_VALUE) 1806: set(- (long) len); 1807: else 1808: set(-len); 1809: return; 1810: } 1811: realloc(len + 1); 1812: if (negate(words, x.words, len)) 1813: words[len++] = 0; 1814: ival = len; 1815: } 1816: 1817: 1818: private void setNegative() 1819: { 1820: setNegative(this); 1821: } 1822: 1823: private static BigInteger abs(BigInteger x) 1824: { 1825: return x.isNegative() ? neg(x) : x; 1826: } 1827: 1828: public BigInteger abs() 1829: { 1830: return abs(this); 1831: } 1832: 1833: private static BigInteger neg(BigInteger x) 1834: { 1835: if (x.words == null && x.ival != Integer.MIN_VALUE) 1836: return valueOf(- x.ival); 1837: BigInteger result = new BigInteger(0); 1838: result.setNegative(x); 1839: return result.canonicalize(); 1840: } 1841: 1842: public BigInteger negate() 1843: { 1844: return neg(this); 1845: } 1846: 1847: 1850: public int bitLength() 1851: { 1852: if (words == null) 1853: return MPN.intLength(ival); 1854: return MPN.intLength(words, ival); 1855: } 1856: 1857: public byte[] toByteArray() 1858: { 1859: 1860: 1861: 1862: byte[] bytes = new byte[(bitLength() + 1 + 7) / 8]; 1863: int nbytes = bytes.length; 1864: 1865: int wptr = 0; 1866: int word; 1867: 1868: 1869: 1870: while (nbytes > 4) 1871: { 1872: word = words[wptr++]; 1873: for (int i = 4; i > 0; --i, word >>= 8) 1874: bytes[--nbytes] = (byte) word; 1875: } 1876: 1877: 1878: word = (words == null) ? ival : words[wptr]; 1879: for ( ; nbytes > 0; word >>= 8) 1880: bytes[--nbytes] = (byte) word; 1881: 1882: return bytes; 1883: } 1884: 1885: 1888: private static int swappedOp(int op) 1889: { 1890: return 1891: "\000\001\004\005\002\003\006\007\010\011\014\015\012\013\016\017" 1892: .charAt(op); 1893: } 1894: 1895: 1896: private static BigInteger bitOp(int op, BigInteger x, BigInteger y) 1897: { 1898: switch (op) 1899: { 1900: case 0: return ZERO; 1901: case 1: return x.and(y); 1902: case 3: return x; 1903: case 5: return y; 1904: case 15: return valueOf(-1); 1905: } 1906: BigInteger result = new BigInteger(); 1907: setBitOp(result, op, x, y); 1908: return result.canonicalize(); 1909: } 1910: 1911: 1912: private static void setBitOp(BigInteger result, int op, 1913: BigInteger x, BigInteger y) 1914: { 1915: if ((y.words != null) && (x.words == null || x.ival < y.ival)) 1916: { 1917: BigInteger temp = x; x = y; y = temp; 1918: op = swappedOp(op); 1919: } 1920: int xi; 1921: int yi; 1922: int xlen, ylen; 1923: if (y.words == null) 1924: { 1925: yi = y.ival; 1926: ylen = 1; 1927: } 1928: else 1929: { 1930: yi = y.words[0]; 1931: ylen = y.ival; 1932: } 1933: if (x.words == null) 1934: { 1935: xi = x.ival; 1936: xlen = 1; 1937: } 1938: else 1939: { 1940: xi = x.words[0]; 1941: xlen = x.ival; 1942: } 1943: if (xlen > 1) 1944: result.realloc(xlen); 1945: int[] w = result.words; 1946: int i = 0; 1947: 1948: 1949: 1950: 1951: int finish = 0; 1952: int ni; 1953: switch (op) 1954: { 1955: case 0: 1956: ni = 0; 1957: break; 1958: case 1: 1959: for (;;) 1960: { 1961: ni = xi & yi; 1962: if (i+1 >= ylen) break; 1963: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 1964: } 1965: if (yi < 0) finish = 1; 1966: break; 1967: case 2: 1968: for (;;) 1969: { 1970: ni = xi & ~yi; 1971: if (i+1 >= ylen) break; 1972: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 1973: } 1974: if (yi >= 0) finish = 1; 1975: break; 1976: case 3: 1977: ni = xi; 1978: finish = 1; 1979: break; 1980: case 4: 1981: for (;;) 1982: { 1983: ni = ~xi & yi; 1984: if (i+1 >= ylen) break; 1985: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 1986: } 1987: if (yi < 0) finish = 2; 1988: break; 1989: case 5: 1990: for (;;) 1991: { 1992: ni = yi; 1993: if (i+1 >= ylen) break; 1994: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 1995: } 1996: break; 1997: case 6: 1998: for (;;) 1999: { 2000: ni = xi ^ yi; 2001: if (i+1 >= ylen) break; 2002: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 2003: } 2004: finish = yi < 0 ? 2 : 1; 2005: break; 2006: case 7: 2007: for (;;) 2008: { 2009: ni = xi | yi; 2010: if (i+1 >= ylen) break; 2011: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 2012: } 2013: if (yi >= 0) finish = 1; 2014: break; 2015: case 8: 2016: for (;;) 2017: { 2018: ni = ~(xi | yi); 2019: if (i+1 >= ylen) break; 2020: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 2021: } 2022: if (yi >= 0) finish = 2; 2023: break; 2024: case 9: 2025: for (;;) 2026: { 2027: ni = ~(xi ^ yi); 2028: if (i+1 >= ylen) break; 2029: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 2030: } 2031: finish = yi >= 0 ? 2 : 1; 2032: break; 2033: case 10: 2034: for (;;) 2035: { 2036: ni = ~yi; 2037: if (i+1 >= ylen) break; 2038: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 2039: } 2040: break; 2041: case 11: 2042: for (;;) 2043: { 2044: ni = xi | ~yi; 2045: if (i+1 >= ylen) break; 2046: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 2047: } 2048: if (yi < 0) finish = 1; 2049: break; 2050: case 12: 2051: ni = ~xi; 2052: finish = 2; 2053: break; 2054: case 13: 2055: for (;;) 2056: { 2057: ni = ~xi | yi; 2058: if (i+1 >= ylen) break; 2059: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 2060: } 2061: if (yi >= 0) finish = 2; 2062: break; 2063: case 14: 2064: for (;;) 2065: { 2066: ni = ~(xi & yi); 2067: if (i+1 >= ylen) break; 2068: w[i++] = ni; xi = x.words[i]; yi = y.words[i]; 2069: } 2070: if (yi < 0) finish = 2; 2071: break; 2072: default: 2073: case 15: 2074: ni = -1; 2075: break; 2076: } 2077: 2078: 2079: if (i+1 == xlen) 2080: finish = 0; 2081: switch (finish) 2082: { 2083: case 0: 2084: if (i == 0 && w == null) 2085: { 2086: result.ival = ni; 2087: return; 2088: } 2089: w[i++] = ni; 2090: break; 2091: case 1: w[i] = ni; while (++i < xlen) w[i] = x.words[i]; break; 2092: case 2: w[i] = ni; while (++i < xlen) w[i] = ~x.words[i]; break; 2093: } 2094: result.ival = i; 2095: } 2096: 2097: 2098: private static BigInteger and(BigInteger x, int y) 2099: { 2100: if (x.words == null) 2101: return valueOf(x.ival & y); 2102: if (y >= 0) 2103: return valueOf(x.words[0] & y); 2104: int len = x.ival; 2105: int[] words = new int[len]; 2106: words[0] = x.words[0] & y; 2107: while (--len > 0) 2108: words[len] = x.words[len]; 2109: return make(words, x.ival); 2110: } 2111: 2112: 2113: public BigInteger and(BigInteger y) 2114: { 2115: if (y.words == null) 2116: return and(this, y.ival); 2117: else if (words == null) 2118: return and(y, ival); 2119: 2120: BigInteger x = this; 2121: if (ival < y.ival) 2122: { 2123: BigInteger temp = this; x = y; y = temp; 2124: } 2125: int i; 2126: int len = y.isNegative() ? x.ival : y.ival; 2127: int[] words = new int[len]; 2128: for (i = 0; i < y.ival; i++) 2129: words[i] = x.words[i] & y.words[i]; 2130: for ( ; i < len; i++) 2131: words[i] = x.words[i]; 2132: return make(words, len); 2133: } 2134: 2135: 2136: public BigInteger or(BigInteger y) 2137: { 2138: return bitOp(7, this, y); 2139: } 2140: 2141: 2142: public BigInteger xor(BigInteger y) 2143: { 2144: return bitOp(6, this, y); 2145: } 2146: 2147: 2148: public BigInteger not() 2149: { 2150: return bitOp(12, this, ZERO); 2151: } 2152: 2153: public BigInteger andNot(BigInteger val) 2154: { 2155: return and(val.not()); 2156: } 2157: 2158: public BigInteger clearBit(int n) 2159: { 2160: if (n < 0) 2161: throw new ArithmeticException(); 2162: 2163: return and(ONE.shiftLeft(n).not()); 2164: } 2165: 2166: public BigInteger setBit(int n) 2167: { 2168: if (n < 0) 2169: throw new ArithmeticException(); 2170: 2171: return or(ONE.shiftLeft(n)); 2172: } 2173: 2174: public boolean testBit(int n) 2175: { 2176: if (n < 0) 2177: throw new ArithmeticException(); 2178: 2179: return !and(ONE.shiftLeft(n)).isZero(); 2180: } 2181: 2182: public BigInteger flipBit(int n) 2183: { 2184: if (n < 0) 2185: throw new ArithmeticException(); 2186: 2187: return xor(ONE.shiftLeft(n)); 2188: } 2189: 2190: public int getLowestSetBit() 2191: { 2192: if (isZero()) 2193: return -1; 2194: 2195: if (words == null) 2196: return MPN.findLowestBit(ival); 2197: else 2198: return MPN.findLowestBit(words); 2199: } 2200: 2201: 2202: private static final byte[] bit4_count = { 0, 1, 1, 2, 1, 2, 2, 3, 2203: 1, 2, 2, 3, 2, 3, 3, 4}; 2204: 2205: private static int bitCount(int i) 2206: { 2207: int count = 0; 2208: while (i != 0) 2209: { 2210: count += bit4_count[i & 15]; 2211: i >>>= 4; 2212: } 2213: return count; 2214: } 2215: 2216: private static int bitCount(int[] x, int len) 2217: { 2218: int count = 0; 2219: while (--len >= 0) 2220: count += bitCount(x[len]); 2221: return count; 2222: } 2223: 2224: 2226: public int bitCount() 2227: { 2228: int i, x_len; 2229: int[] x_words = words; 2230: if (x_words == null) 2231: { 2232: x_len = 1; 2233: i = bitCount(ival); 2234: } 2235: else 2236: { 2237: x_len = ival; 2238: i = bitCount(x_words, x_len); 2239: } 2240: return isNegative() ? x_len * 32 - i : i; 2241: } 2242: 2243: private void readObject(ObjectInputStream s) 2244: throws IOException, ClassNotFoundException 2245: { 2246: s.defaultReadObject(); 2247: if (magnitude.length == 0 || signum == 0) 2248: { 2249: this.ival = 0; 2250: this.words = null; 2251: } 2252: else 2253: { 2254: words = byteArrayToIntArray(magnitude, signum < 0 ? -1 : 0); 2255: BigInteger result = make(words, words.length); 2256: this.ival = result.ival; 2257: this.words = result.words; 2258: } 2259: } 2260: 2261: private void writeObject(ObjectOutputStream s) 2262: throws IOException, ClassNotFoundException 2263: { 2264: signum = signum(); 2265: magnitude = signum == 0 ? new byte[0] : toByteArray(); 2266: s.defaultWriteObject(); 2267: } 2268: }