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: }