1
25
26 package java.math;
27
28
44
45 import static java.math.BigDecimal.INFLATED;
46 import static java.math.BigInteger.LONG_MASK;
47 import java.util.Arrays;
48
49 class MutableBigInteger {
50
55 int[] value;
56
57
62 int intLen;
63
64
68 int offset = 0;
69
70
71
76 static final MutableBigInteger ONE = new MutableBigInteger(1);
77
78
85 static final int KNUTH_POW2_THRESH_LEN = 6;
86
87
94 static final int KNUTH_POW2_THRESH_ZEROS = 3;
95
96
97
98
102 MutableBigInteger() {
103 value = new int[1];
104 intLen = 0;
105 }
106
107
111 MutableBigInteger(int val) {
112 value = new int[1];
113 intLen = 1;
114 value[0] = val;
115 }
116
117
121 MutableBigInteger(int[] val) {
122 value = val;
123 intLen = val.length;
124 }
125
126
130 MutableBigInteger(BigInteger b) {
131 intLen = b.mag.length;
132 value = Arrays.copyOf(b.mag, intLen);
133 }
134
135
139 MutableBigInteger(MutableBigInteger val) {
140 intLen = val.intLen;
141 value = Arrays.copyOfRange(val.value, val.offset, val.offset + intLen);
142 }
143
144
150 private void ones(int n) {
151 if (n > value.length)
152 value = new int[n];
153 Arrays.fill(value, -1);
154 offset = 0;
155 intLen = n;
156 }
157
158
162 private int[] getMagnitudeArray() {
163 if (offset > 0 || value.length != intLen)
164 return Arrays.copyOfRange(value, offset, offset + intLen);
165 return value;
166 }
167
168
172 private long toLong() {
173 assert (intLen <= 2) : "this MutableBigInteger exceeds the range of long";
174 if (intLen == 0)
175 return 0;
176 long d = value[offset] & LONG_MASK;
177 return (intLen == 2) ? d << 32 | (value[offset + 1] & LONG_MASK) : d;
178 }
179
180
183 BigInteger toBigInteger(int sign) {
184 if (intLen == 0 || sign == 0)
185 return BigInteger.ZERO;
186 return new BigInteger(getMagnitudeArray(), sign);
187 }
188
189
192 BigInteger toBigInteger() {
193 normalize();
194 return toBigInteger(isZero() ? 0 : 1);
195 }
196
197
201 BigDecimal toBigDecimal(int sign, int scale) {
202 if (intLen == 0 || sign == 0)
203 return BigDecimal.zeroValueOf(scale);
204 int[] mag = getMagnitudeArray();
205 int len = mag.length;
206 int d = mag[0];
207
208
209 if (len > 2 || (d < 0 && len == 2))
210 return new BigDecimal(new BigInteger(mag, sign), INFLATED, scale, 0);
211 long v = (len == 2) ?
212 ((mag[1] & LONG_MASK) | (d & LONG_MASK) << 32) :
213 d & LONG_MASK;
214 return BigDecimal.valueOf(sign == -1 ? -v : v, scale);
215 }
216
217
222 long toCompactValue(int sign) {
223 if (intLen == 0 || sign == 0)
224 return 0L;
225 int[] mag = getMagnitudeArray();
226 int len = mag.length;
227 int d = mag[0];
228
229
230 if (len > 2 || (d < 0 && len == 2))
231 return INFLATED;
232 long v = (len == 2) ?
233 ((mag[1] & LONG_MASK) | (d & LONG_MASK) << 32) :
234 d & LONG_MASK;
235 return sign == -1 ? -v : v;
236 }
237
238
241 void clear() {
242 offset = intLen = 0;
243 for (int index=0, n=value.length; index < n; index++)
244 value[index] = 0;
245 }
246
247
250 void reset() {
251 offset = intLen = 0;
252 }
253
254
259 final int compare(MutableBigInteger b) {
260 int blen = b.intLen;
261 if (intLen < blen)
262 return -1;
263 if (intLen > blen)
264 return 1;
265
266
267
268 int[] bval = b.value;
269 for (int i = offset, j = b.offset; i < intLen + offset; i++, j++) {
270 int b1 = value[i] + 0x80000000;
271 int b2 = bval[j] + 0x80000000;
272 if (b1 < b2)
273 return -1;
274 if (b1 > b2)
275 return 1;
276 }
277 return 0;
278 }
279
280
284 private int compareShifted(MutableBigInteger b, int ints) {
285 int blen = b.intLen;
286 int alen = intLen - ints;
287 if (alen < blen)
288 return -1;
289 if (alen > blen)
290 return 1;
291
292
293
294 int[] bval = b.value;
295 for (int i = offset, j = b.offset; i < alen + offset; i++, j++) {
296 int b1 = value[i] + 0x80000000;
297 int b2 = bval[j] + 0x80000000;
298 if (b1 < b2)
299 return -1;
300 if (b1 > b2)
301 return 1;
302 }
303 return 0;
304 }
305
306
312 final int compareHalf(MutableBigInteger b) {
313 int blen = b.intLen;
314 int len = intLen;
315 if (len <= 0)
316 return blen <= 0 ? 0 : -1;
317 if (len > blen)
318 return 1;
319 if (len < blen - 1)
320 return -1;
321 int[] bval = b.value;
322 int bstart = 0;
323 int carry = 0;
324
325 if (len != blen) {
326 if (bval[bstart] == 1) {
327 ++bstart;
328 carry = 0x80000000;
329 } else
330 return -1;
331 }
332
333
334 int[] val = value;
335 for (int i = offset, j = bstart; i < len + offset;) {
336 int bv = bval[j++];
337 long hb = ((bv >>> 1) + carry) & LONG_MASK;
338 long v = val[i++] & LONG_MASK;
339 if (v != hb)
340 return v < hb ? -1 : 1;
341 carry = (bv & 1) << 31;
342 }
343 return carry == 0 ? 0 : -1;
344 }
345
346
350 private final int getLowestSetBit() {
351 if (intLen == 0)
352 return -1;
353 int j, b;
354 for (j=intLen-1; (j > 0) && (value[j+offset] == 0); j--)
355 ;
356 b = value[j+offset];
357 if (b == 0)
358 return -1;
359 return ((intLen-1-j)<<5) + Integer.numberOfTrailingZeros(b);
360 }
361
362
367 private final int getInt(int index) {
368 return value[offset+index];
369 }
370
371
376 private final long getLong(int index) {
377 return value[offset+index] & LONG_MASK;
378 }
379
380
385 final void normalize() {
386 if (intLen == 0) {
387 offset = 0;
388 return;
389 }
390
391 int index = offset;
392 if (value[index] != 0)
393 return;
394
395 int indexBound = index+intLen;
396 do {
397 index++;
398 } while(index < indexBound && value[index] == 0);
399
400 int numZeros = index - offset;
401 intLen -= numZeros;
402 offset = (intLen == 0 ? 0 : offset+numZeros);
403 }
404
405
409 private final void ensureCapacity(int len) {
410 if (value.length < len) {
411 value = new int[len];
412 offset = 0;
413 intLen = len;
414 }
415 }
416
417
421 int[] toIntArray() {
422 int[] result = new int[intLen];
423 for(int i=0; i < intLen; i++)
424 result[i] = value[offset+i];
425 return result;
426 }
427
428
433 void setInt(int index, int val) {
434 value[offset + index] = val;
435 }
436
437
441 void setValue(int[] val, int length) {
442 value = val;
443 intLen = length;
444 offset = 0;
445 }
446
447
451 void copyValue(MutableBigInteger src) {
452 int len = src.intLen;
453 if (value.length < len)
454 value = new int[len];
455 System.arraycopy(src.value, src.offset, value, 0, len);
456 intLen = len;
457 offset = 0;
458 }
459
460
464 void copyValue(int[] val) {
465 int len = val.length;
466 if (value.length < len)
467 value = new int[len];
468 System.arraycopy(val, 0, value, 0, len);
469 intLen = len;
470 offset = 0;
471 }
472
473
476 boolean isOne() {
477 return (intLen == 1) && (value[offset] == 1);
478 }
479
480
483 boolean isZero() {
484 return (intLen == 0);
485 }
486
487
490 boolean isEven() {
491 return (intLen == 0) || ((value[offset + intLen - 1] & 1) == 0);
492 }
493
494
497 boolean isOdd() {
498 return isZero() ? false : ((value[offset + intLen - 1] & 1) == 1);
499 }
500
501
506 boolean isNormal() {
507 if (intLen + offset > value.length)
508 return false;
509 if (intLen == 0)
510 return true;
511 return (value[offset] != 0);
512 }
513
514
517 public String toString() {
518 BigInteger b = toBigInteger(1);
519 return b.toString();
520 }
521
522
525 void safeRightShift(int n) {
526 if (n/32 >= intLen) {
527 reset();
528 } else {
529 rightShift(n);
530 }
531 }
532
533
537 void rightShift(int n) {
538 if (intLen == 0)
539 return;
540 int nInts = n >>> 5;
541 int nBits = n & 0x1F;
542 this.intLen -= nInts;
543 if (nBits == 0)
544 return;
545 int bitsInHighWord = BigInteger.bitLengthForInt(value[offset]);
546 if (nBits >= bitsInHighWord) {
547 this.primitiveLeftShift(32 - nBits);
548 this.intLen--;
549 } else {
550 primitiveRightShift(nBits);
551 }
552 }
553
554
557 void safeLeftShift(int n) {
558 if (n > 0) {
559 leftShift(n);
560 }
561 }
562
563
566 void leftShift(int n) {
567
573 if (intLen == 0)
574 return;
575 int nInts = n >>> 5;
576 int nBits = n&0x1F;
577 int bitsInHighWord = BigInteger.bitLengthForInt(value[offset]);
578
579
580 if (n <= (32-bitsInHighWord)) {
581 primitiveLeftShift(nBits);
582 return;
583 }
584
585 int newLen = intLen + nInts +1;
586 if (nBits <= (32-bitsInHighWord))
587 newLen--;
588 if (value.length < newLen) {
589
590 int[] result = new int[newLen];
591 for (int i=0; i < intLen; i++)
592 result[i] = value[offset+i];
593 setValue(result, newLen);
594 } else if (value.length - offset >= newLen) {
595
596 for(int i=0; i < newLen - intLen; i++)
597 value[offset+intLen+i] = 0;
598 } else {
599
600 for (int i=0; i < intLen; i++)
601 value[i] = value[offset+i];
602 for (int i=intLen; i < newLen; i++)
603 value[i] = 0;
604 offset = 0;
605 }
606 intLen = newLen;
607 if (nBits == 0)
608 return;
609 if (nBits <= (32-bitsInHighWord))
610 primitiveLeftShift(nBits);
611 else
612 primitiveRightShift(32 -nBits);
613 }
614
615
620 private int divadd(int[] a, int[] result, int offset) {
621 long carry = 0;
622
623 for (int j=a.length-1; j >= 0; j--) {
624 long sum = (a[j] & LONG_MASK) +
625 (result[j+offset] & LONG_MASK) + carry;
626 result[j+offset] = (int)sum;
627 carry = sum >>> 32;
628 }
629 return (int)carry;
630 }
631
632
637 private int mulsub(int[] q, int[] a, int x, int len, int offset) {
638 long xLong = x & LONG_MASK;
639 long carry = 0;
640 offset += len;
641
642 for (int j=len-1; j >= 0; j--) {
643 long product = (a[j] & LONG_MASK) * xLong + carry;
644 long difference = q[offset] - product;
645 q[offset--] = (int)difference;
646 carry = (product >>> 32)
647 + (((difference & LONG_MASK) >
648 (((~(int)product) & LONG_MASK))) ? 1:0);
649 }
650 return (int)carry;
651 }
652
653
657 private int mulsubBorrow(int[] q, int[] a, int x, int len, int offset) {
658 long xLong = x & LONG_MASK;
659 long carry = 0;
660 offset += len;
661 for (int j=len-1; j >= 0; j--) {
662 long product = (a[j] & LONG_MASK) * xLong + carry;
663 long difference = q[offset--] - product;
664 carry = (product >>> 32)
665 + (((difference & LONG_MASK) >
666 (((~(int)product) & LONG_MASK))) ? 1:0);
667 }
668 return (int)carry;
669 }
670
671
676 private final void primitiveRightShift(int n) {
677 int[] val = value;
678 int n2 = 32 - n;
679 for (int i=offset+intLen-1, c=val[i]; i > offset; i--) {
680 int b = c;
681 c = val[i-1];
682 val[i] = (c << n2) | (b >>> n);
683 }
684 val[offset] >>>= n;
685 }
686
687
692 private final void primitiveLeftShift(int n) {
693 int[] val = value;
694 int n2 = 32 - n;
695 for (int i=offset, c=val[i], m=i+intLen-1; i < m; i++) {
696 int b = c;
697 c = val[i+1];
698 val[i] = (b << n) | (c >>> n2);
699 }
700 val[offset+intLen-1] <<= n;
701 }
702
703
707 private BigInteger getLower(int n) {
708 if (isZero()) {
709 return BigInteger.ZERO;
710 } else if (intLen < n) {
711 return toBigInteger(1);
712 } else {
713
714 int len = n;
715 while (len > 0 && value[offset+intLen-len] == 0)
716 len--;
717 int sign = len > 0 ? 1 : 0;
718 return new BigInteger(Arrays.copyOfRange(value, offset+intLen-len, offset+intLen), sign);
719 }
720 }
721
722
725 private void keepLower(int n) {
726 if (intLen >= n) {
727 offset += intLen - n;
728 intLen = n;
729 }
730 }
731
732
737 void add(MutableBigInteger addend) {
738 int x = intLen;
739 int y = addend.intLen;
740 int resultLen = (intLen > addend.intLen ? intLen : addend.intLen);
741 int[] result = (value.length < resultLen ? new int[resultLen] : value);
742
743 int rstart = result.length-1;
744 long sum;
745 long carry = 0;
746
747
748 while(x > 0 && y > 0) {
749 x--; y--;
750 sum = (value[x+offset] & LONG_MASK) +
751 (addend.value[y+addend.offset] & LONG_MASK) + carry;
752 result[rstart--] = (int)sum;
753 carry = sum >>> 32;
754 }
755
756
757 while(x > 0) {
758 x--;
759 if (carry == 0 && result == value && rstart == (x + offset))
760 return;
761 sum = (value[x+offset] & LONG_MASK) + carry;
762 result[rstart--] = (int)sum;
763 carry = sum >>> 32;
764 }
765 while(y > 0) {
766 y--;
767 sum = (addend.value[y+addend.offset] & LONG_MASK) + carry;
768 result[rstart--] = (int)sum;
769 carry = sum >>> 32;
770 }
771
772 if (carry > 0) {
773 resultLen++;
774 if (result.length < resultLen) {
775 int temp[] = new int[resultLen];
776
777
778 System.arraycopy(result, 0, temp, 1, result.length);
779 temp[0] = 1;
780 result = temp;
781 } else {
782 result[rstart--] = 1;
783 }
784 }
785
786 value = result;
787 intLen = resultLen;
788 offset = result.length - resultLen;
789 }
790
791
796 void addShifted(MutableBigInteger addend, int n) {
797 if (addend.isZero()) {
798 return;
799 }
800
801 int x = intLen;
802 int y = addend.intLen + n;
803 int resultLen = (intLen > y ? intLen : y);
804 int[] result = (value.length < resultLen ? new int[resultLen] : value);
805
806 int rstart = result.length-1;
807 long sum;
808 long carry = 0;
809
810
811 while (x > 0 && y > 0) {
812 x--; y--;
813 int bval = y+addend.offset < addend.value.length ? addend.value[y+addend.offset] : 0;
814 sum = (value[x+offset] & LONG_MASK) +
815 (bval & LONG_MASK) + carry;
816 result[rstart--] = (int)sum;
817 carry = sum >>> 32;
818 }
819
820
821 while (x > 0) {
822 x--;
823 if (carry == 0 && result == value && rstart == (x + offset)) {
824 return;
825 }
826 sum = (value[x+offset] & LONG_MASK) + carry;
827 result[rstart--] = (int)sum;
828 carry = sum >>> 32;
829 }
830 while (y > 0) {
831 y--;
832 int bval = y+addend.offset < addend.value.length ? addend.value[y+addend.offset] : 0;
833 sum = (bval & LONG_MASK) + carry;
834 result[rstart--] = (int)sum;
835 carry = sum >>> 32;
836 }
837
838 if (carry > 0) {
839 resultLen++;
840 if (result.length < resultLen) {
841 int temp[] = new int[resultLen];
842
843
844 System.arraycopy(result, 0, temp, 1, result.length);
845 temp[0] = 1;
846 result = temp;
847 } else {
848 result[rstart--] = 1;
849 }
850 }
851
852 value = result;
853 intLen = resultLen;
854 offset = result.length - resultLen;
855 }
856
857
862 void addDisjoint(MutableBigInteger addend, int n) {
863 if (addend.isZero())
864 return;
865
866 int x = intLen;
867 int y = addend.intLen + n;
868 int resultLen = (intLen > y ? intLen : y);
869 int[] result;
870 if (value.length < resultLen)
871 result = new int[resultLen];
872 else {
873 result = value;
874 Arrays.fill(value, offset+intLen, value.length, 0);
875 }
876
877 int rstart = result.length-1;
878
879
880 System.arraycopy(value, offset, result, rstart+1-x, x);
881 y -= x;
882 rstart -= x;
883
884 int len = Math.min(y, addend.value.length-addend.offset);
885 System.arraycopy(addend.value, addend.offset, result, rstart+1-y, len);
886
887
888 for (int i=rstart+1-y+len; i < rstart+1; i++)
889 result[i] = 0;
890
891 value = result;
892 intLen = resultLen;
893 offset = result.length - resultLen;
894 }
895
896
899 void addLower(MutableBigInteger addend, int n) {
900 MutableBigInteger a = new MutableBigInteger(addend);
901 if (a.offset + a.intLen >= n) {
902 a.offset = a.offset + a.intLen - n;
903 a.intLen = n;
904 }
905 a.normalize();
906 add(a);
907 }
908
909
913 int subtract(MutableBigInteger b) {
914 MutableBigInteger a = this;
915
916 int[] result = value;
917 int sign = a.compare(b);
918
919 if (sign == 0) {
920 reset();
921 return 0;
922 }
923 if (sign < 0) {
924 MutableBigInteger tmp = a;
925 a = b;
926 b = tmp;
927 }
928
929 int resultLen = a.intLen;
930 if (result.length < resultLen)
931 result = new int[resultLen];
932
933 long diff = 0;
934 int x = a.intLen;
935 int y = b.intLen;
936 int rstart = result.length - 1;
937
938
939 while (y > 0) {
940 x--; y--;
941
942 diff = (a.value[x+a.offset] & LONG_MASK) -
943 (b.value[y+b.offset] & LONG_MASK) - ((int)-(diff>>32));
944 result[rstart--] = (int)diff;
945 }
946
947 while (x > 0) {
948 x--;
949 diff = (a.value[x+a.offset] & LONG_MASK) - ((int)-(diff>>32));
950 result[rstart--] = (int)diff;
951 }
952
953 value = result;
954 intLen = resultLen;
955 offset = value.length - resultLen;
956 normalize();
957 return sign;
958 }
959
960
965 private int difference(MutableBigInteger b) {
966 MutableBigInteger a = this;
967 int sign = a.compare(b);
968 if (sign == 0)
969 return 0;
970 if (sign < 0) {
971 MutableBigInteger tmp = a;
972 a = b;
973 b = tmp;
974 }
975
976 long diff = 0;
977 int x = a.intLen;
978 int y = b.intLen;
979
980
981 while (y > 0) {
982 x--; y--;
983 diff = (a.value[a.offset+ x] & LONG_MASK) -
984 (b.value[b.offset+ y] & LONG_MASK) - ((int)-(diff>>32));
985 a.value[a.offset+x] = (int)diff;
986 }
987
988 while (x > 0) {
989 x--;
990 diff = (a.value[a.offset+ x] & LONG_MASK) - ((int)-(diff>>32));
991 a.value[a.offset+x] = (int)diff;
992 }
993
994 a.normalize();
995 return sign;
996 }
997
998
1002 void multiply(MutableBigInteger y, MutableBigInteger z) {
1003 int xLen = intLen;
1004 int yLen = y.intLen;
1005 int newLen = xLen + yLen;
1006
1007
1008 if (z.value.length < newLen)
1009 z.value = new int[newLen];
1010 z.offset = 0;
1011 z.intLen = newLen;
1012
1013
1014 long carry = 0;
1015 for (int j=yLen-1, k=yLen+xLen-1; j >= 0; j--, k--) {
1016 long product = (y.value[j+y.offset] & LONG_MASK) *
1017 (value[xLen-1+offset] & LONG_MASK) + carry;
1018 z.value[k] = (int)product;
1019 carry = product >>> 32;
1020 }
1021 z.value[xLen-1] = (int)carry;
1022
1023
1024 for (int i = xLen-2; i >= 0; i--) {
1025 carry = 0;
1026 for (int j=yLen-1, k=yLen+i; j >= 0; j--, k--) {
1027 long product = (y.value[j+y.offset] & LONG_MASK) *
1028 (value[i+offset] & LONG_MASK) +
1029 (z.value[k] & LONG_MASK) + carry;
1030 z.value[k] = (int)product;
1031 carry = product >>> 32;
1032 }
1033 z.value[i] = (int)carry;
1034 }
1035
1036
1037 z.normalize();
1038 }
1039
1040
1044 void mul(int y, MutableBigInteger z) {
1045 if (y == 1) {
1046 z.copyValue(this);
1047 return;
1048 }
1049
1050 if (y == 0) {
1051 z.clear();
1052 return;
1053 }
1054
1055
1056 long ylong = y & LONG_MASK;
1057 int[] zval = (z.value.length < intLen+1 ? new int[intLen + 1]
1058 : z.value);
1059 long carry = 0;
1060 for (int i = intLen-1; i >= 0; i--) {
1061 long product = ylong * (value[i+offset] & LONG_MASK) + carry;
1062 zval[i+1] = (int)product;
1063 carry = product >>> 32;
1064 }
1065
1066 if (carry == 0) {
1067 z.offset = 1;
1068 z.intLen = intLen;
1069 } else {
1070 z.offset = 0;
1071 z.intLen = intLen + 1;
1072 zval[0] = (int)carry;
1073 }
1074 z.value = zval;
1075 }
1076
1077
1085 int divideOneWord(int divisor, MutableBigInteger quotient) {
1086 long divisorLong = divisor & LONG_MASK;
1087
1088
1089 if (intLen == 1) {
1090 long dividendValue = value[offset] & LONG_MASK;
1091 int q = (int) (dividendValue / divisorLong);
1092 int r = (int) (dividendValue - q * divisorLong);
1093 quotient.value[0] = q;
1094 quotient.intLen = (q == 0) ? 0 : 1;
1095 quotient.offset = 0;
1096 return r;
1097 }
1098
1099 if (quotient.value.length < intLen)
1100 quotient.value = new int[intLen];
1101 quotient.offset = 0;
1102 quotient.intLen = intLen;
1103
1104
1105 int shift = Integer.numberOfLeadingZeros(divisor);
1106
1107 int rem = value[offset];
1108 long remLong = rem & LONG_MASK;
1109 if (remLong < divisorLong) {
1110 quotient.value[0] = 0;
1111 } else {
1112 quotient.value[0] = (int)(remLong / divisorLong);
1113 rem = (int) (remLong - (quotient.value[0] * divisorLong));
1114 remLong = rem & LONG_MASK;
1115 }
1116 int xlen = intLen;
1117 while (--xlen > 0) {
1118 long dividendEstimate = (remLong << 32) |
1119 (value[offset + intLen - xlen] & LONG_MASK);
1120 int q;
1121 if (dividendEstimate >= 0) {
1122 q = (int) (dividendEstimate / divisorLong);
1123 rem = (int) (dividendEstimate - q * divisorLong);
1124 } else {
1125 long tmp = divWord(dividendEstimate, divisor);
1126 q = (int) (tmp & LONG_MASK);
1127 rem = (int) (tmp >>> 32);
1128 }
1129 quotient.value[intLen - xlen] = q;
1130 remLong = rem & LONG_MASK;
1131 }
1132
1133 quotient.normalize();
1134
1135 if (shift > 0)
1136 return rem % divisor;
1137 else
1138 return rem;
1139 }
1140
1141
1146 MutableBigInteger divide(MutableBigInteger b, MutableBigInteger quotient) {
1147 return divide(b,quotient,true);
1148 }
1149
1150 MutableBigInteger divide(MutableBigInteger b, MutableBigInteger quotient, boolean needRemainder) {
1151 if (b.intLen < BigInteger.BURNIKEL_ZIEGLER_THRESHOLD ||
1152 intLen - b.intLen < BigInteger.BURNIKEL_ZIEGLER_OFFSET) {
1153 return divideKnuth(b, quotient, needRemainder);
1154 } else {
1155 return divideAndRemainderBurnikelZiegler(b, quotient);
1156 }
1157 }
1158
1159
1162 MutableBigInteger divideKnuth(MutableBigInteger b, MutableBigInteger quotient) {
1163 return divideKnuth(b,quotient,true);
1164 }
1165
1166
1177 MutableBigInteger divideKnuth(MutableBigInteger b, MutableBigInteger quotient, boolean needRemainder) {
1178 if (b.intLen == 0)
1179 throw new ArithmeticException("BigInteger divide by zero");
1180
1181
1182 if (intLen == 0) {
1183 quotient.intLen = quotient.offset = 0;
1184 return needRemainder ? new MutableBigInteger() : null;
1185 }
1186
1187 int cmp = compare(b);
1188
1189 if (cmp < 0) {
1190 quotient.intLen = quotient.offset = 0;
1191 return needRemainder ? new MutableBigInteger(this) : null;
1192 }
1193
1194 if (cmp == 0) {
1195 quotient.value[0] = quotient.intLen = 1;
1196 quotient.offset = 0;
1197 return needRemainder ? new MutableBigInteger() : null;
1198 }
1199
1200 quotient.clear();
1201
1202 if (b.intLen == 1) {
1203 int r = divideOneWord(b.value[b.offset], quotient);
1204 if(needRemainder) {
1205 if (r == 0)
1206 return new MutableBigInteger();
1207 return new MutableBigInteger(r);
1208 } else {
1209 return null;
1210 }
1211 }
1212
1213
1214 if (intLen >= KNUTH_POW2_THRESH_LEN) {
1215 int trailingZeroBits = Math.min(getLowestSetBit(), b.getLowestSetBit());
1216 if (trailingZeroBits >= KNUTH_POW2_THRESH_ZEROS*32) {
1217 MutableBigInteger a = new MutableBigInteger(this);
1218 b = new MutableBigInteger(b);
1219 a.rightShift(trailingZeroBits);
1220 b.rightShift(trailingZeroBits);
1221 MutableBigInteger r = a.divideKnuth(b, quotient);
1222 r.leftShift(trailingZeroBits);
1223 return r;
1224 }
1225 }
1226
1227 return divideMagnitude(b, quotient, needRemainder);
1228 }
1229
1230
1241 MutableBigInteger divideAndRemainderBurnikelZiegler(MutableBigInteger b, MutableBigInteger quotient) {
1242 int r = intLen;
1243 int s = b.intLen;
1244
1245
1246 quotient.offset = quotient.intLen = 0;
1247
1248 if (r < s) {
1249 return this;
1250 } else {
1251
1252
1253
1254
1255
1256 int m = 1 << (32-Integer.numberOfLeadingZeros(s/BigInteger.BURNIKEL_ZIEGLER_THRESHOLD));
1257
1258 int j = (s+m-1) / m;
1259 int n = j * m;
1260 long n32 = 32L * n;
1261 int sigma = (int) Math.max(0, n32 - b.bitLength());
1262 MutableBigInteger bShifted = new MutableBigInteger(b);
1263 bShifted.safeLeftShift(sigma);
1264 MutableBigInteger aShifted = new MutableBigInteger (this);
1265 aShifted.safeLeftShift(sigma);
1266
1267
1268 int t = (int) ((aShifted.bitLength()+n32) / n32);
1269 if (t < 2) {
1270 t = 2;
1271 }
1272
1273
1274 MutableBigInteger a1 = aShifted.getBlock(t-1, t, n);
1275
1276
1277 MutableBigInteger z = aShifted.getBlock(t-2, t, n);
1278 z.addDisjoint(a1, n);
1279
1280
1281 MutableBigInteger qi = new MutableBigInteger();
1282 MutableBigInteger ri;
1283 for (int i=t-2; i > 0; i--) {
1284
1285 ri = z.divide2n1n(bShifted, qi);
1286
1287
1288 z = aShifted.getBlock(i-1, t, n);
1289 z.addDisjoint(ri, n);
1290 quotient.addShifted(qi, i*n);
1291 }
1292
1293 ri = z.divide2n1n(bShifted, qi);
1294 quotient.add(qi);
1295
1296 ri.rightShift(sigma);
1297 return ri;
1298 }
1299 }
1300
1301
1311 private MutableBigInteger divide2n1n(MutableBigInteger b, MutableBigInteger quotient) {
1312 int n = b.intLen;
1313
1314
1315 if (n%2 != 0 || n < BigInteger.BURNIKEL_ZIEGLER_THRESHOLD) {
1316 return divideKnuth(b, quotient);
1317 }
1318
1319
1320 MutableBigInteger aUpper = new MutableBigInteger(this);
1321 aUpper.safeRightShift(32*(n/2));
1322 keepLower(n/2);
1323
1324
1325 MutableBigInteger q1 = new MutableBigInteger();
1326 MutableBigInteger r1 = aUpper.divide3n2n(b, q1);
1327
1328
1329 addDisjoint(r1, n/2);
1330 MutableBigInteger r2 = divide3n2n(b, quotient);
1331
1332
1333 quotient.addDisjoint(q1, n/2);
1334 return r2;
1335 }
1336
1337
1346 private MutableBigInteger divide3n2n(MutableBigInteger b, MutableBigInteger quotient) {
1347 int n = b.intLen / 2;
1348
1349
1350 MutableBigInteger a12 = new MutableBigInteger(this);
1351 a12.safeRightShift(32*n);
1352
1353
1354 MutableBigInteger b1 = new MutableBigInteger(b);
1355 b1.safeRightShift(n * 32);
1356 BigInteger b2 = b.getLower(n);
1357
1358 MutableBigInteger r;
1359 MutableBigInteger d;
1360 if (compareShifted(b, n) < 0) {
1361
1362 r = a12.divide2n1n(b1, quotient);
1363
1364
1365 d = new MutableBigInteger(quotient.toBigInteger().multiply(b2));
1366 } else {
1367
1368 quotient.ones(n);
1369 a12.add(b1);
1370 b1.leftShift(32*n);
1371 a12.subtract(b1);
1372 r = a12;
1373
1374
1375 d = new MutableBigInteger(b2);
1376 d.leftShift(32 * n);
1377 d.subtract(new MutableBigInteger(b2));
1378 }
1379
1380
1381
1382 r.leftShift(32 * n);
1383 r.addLower(this, n);
1384
1385
1386 while (r.compare(d) < 0) {
1387 r.add(b);
1388 quotient.subtract(MutableBigInteger.ONE);
1389 }
1390 r.subtract(d);
1391
1392 return r;
1393 }
1394
1395
1404 private MutableBigInteger getBlock(int index, int numBlocks, int blockLength) {
1405 int blockStart = index * blockLength;
1406 if (blockStart >= intLen) {
1407 return new MutableBigInteger();
1408 }
1409
1410 int blockEnd;
1411 if (index == numBlocks-1) {
1412 blockEnd = intLen;
1413 } else {
1414 blockEnd = (index+1) * blockLength;
1415 }
1416 if (blockEnd > intLen) {
1417 return new MutableBigInteger();
1418 }
1419
1420 int[] newVal = Arrays.copyOfRange(value, offset+intLen-blockEnd, offset+intLen-blockStart);
1421 return new MutableBigInteger(newVal);
1422 }
1423
1424
1425 long bitLength() {
1426 if (intLen == 0)
1427 return 0;
1428 return intLen*32L - Integer.numberOfLeadingZeros(value[offset]);
1429 }
1430
1431
1438 long divide(long v, MutableBigInteger quotient) {
1439 if (v == 0)
1440 throw new ArithmeticException("BigInteger divide by zero");
1441
1442
1443 if (intLen == 0) {
1444 quotient.intLen = quotient.offset = 0;
1445 return 0;
1446 }
1447 if (v < 0)
1448 v = -v;
1449
1450 int d = (int)(v >>> 32);
1451 quotient.clear();
1452
1453 if (d == 0)
1454 return divideOneWord((int)v, quotient) & LONG_MASK;
1455 else {
1456 return divideLongMagnitude(v, quotient).toLong();
1457 }
1458 }
1459
1460 private static void copyAndShift(int[] src, int srcFrom, int srcLen, int[] dst, int dstFrom, int shift) {
1461 int n2 = 32 - shift;
1462 int c=src[srcFrom];
1463 for (int i=0; i < srcLen-1; i++) {
1464 int b = c;
1465 c = src[++srcFrom];
1466 dst[dstFrom+i] = (b << shift) | (c >>> n2);
1467 }
1468 dst[dstFrom+srcLen-1] = c << shift;
1469 }
1470
1471
1476 private MutableBigInteger divideMagnitude(MutableBigInteger div,
1477 MutableBigInteger quotient,
1478 boolean needRemainder ) {
1479
1480
1481 int shift = Integer.numberOfLeadingZeros(div.value[div.offset]);
1482
1483 final int dlen = div.intLen;
1484 int[] divisor;
1485 MutableBigInteger rem;
1486 if (shift > 0) {
1487 divisor = new int[dlen];
1488 copyAndShift(div.value,div.offset,dlen,divisor,0,shift);
1489 if (Integer.numberOfLeadingZeros(value[offset]) >= shift) {
1490 int[] remarr = new int[intLen + 1];
1491 rem = new MutableBigInteger(remarr);
1492 rem.intLen = intLen;
1493 rem.offset = 1;
1494 copyAndShift(value,offset,intLen,remarr,1,shift);
1495 } else {
1496 int[] remarr = new int[intLen + 2];
1497 rem = new MutableBigInteger(remarr);
1498 rem.intLen = intLen+1;
1499 rem.offset = 1;
1500 int rFrom = offset;
1501 int c=0;
1502 int n2 = 32 - shift;
1503 for (int i=1; i < intLen+1; i++,rFrom++) {
1504 int b = c;
1505 c = value[rFrom];
1506 remarr[i] = (b << shift) | (c >>> n2);
1507 }
1508 remarr[intLen+1] = c << shift;
1509 }
1510 } else {
1511 divisor = Arrays.copyOfRange(div.value, div.offset, div.offset + div.intLen);
1512 rem = new MutableBigInteger(new int[intLen + 1]);
1513 System.arraycopy(value, offset, rem.value, 1, intLen);
1514 rem.intLen = intLen;
1515 rem.offset = 1;
1516 }
1517
1518 int nlen = rem.intLen;
1519
1520
1521 final int limit = nlen - dlen + 1;
1522 if (quotient.value.length < limit) {
1523 quotient.value = new int[limit];
1524 quotient.offset = 0;
1525 }
1526 quotient.intLen = limit;
1527 int[] q = quotient.value;
1528
1529
1530
1531 if (rem.intLen == nlen) {
1532 rem.offset = 0;
1533 rem.value[0] = 0;
1534 rem.intLen++;
1535 }
1536
1537 int dh = divisor[0];
1538 long dhLong = dh & LONG_MASK;
1539 int dl = divisor[1];
1540
1541
1542 for (int j=0; j < limit-1; j++) {
1543
1544
1545 int qhat = 0;
1546 int qrem = 0;
1547 boolean skipCorrection = false;
1548 int nh = rem.value[j+rem.offset];
1549 int nh2 = nh + 0x80000000;
1550 int nm = rem.value[j+1+rem.offset];
1551
1552 if (nh == dh) {
1553 qhat = ~0;
1554 qrem = nh + nm;
1555 skipCorrection = qrem + 0x80000000 < nh2;
1556 } else {
1557 long nChunk = (((long)nh) << 32) | (nm & LONG_MASK);
1558 if (nChunk >= 0) {
1559 qhat = (int) (nChunk / dhLong);
1560 qrem = (int) (nChunk - (qhat * dhLong));
1561 } else {
1562 long tmp = divWord(nChunk, dh);
1563 qhat = (int) (tmp & LONG_MASK);
1564 qrem = (int) (tmp >>> 32);
1565 }
1566 }
1567
1568 if (qhat == 0)
1569 continue;
1570
1571 if (!skipCorrection) {
1572 long nl = rem.value[j+2+rem.offset] & LONG_MASK;
1573 long rs = ((qrem & LONG_MASK) << 32) | nl;
1574 long estProduct = (dl & LONG_MASK) * (qhat & LONG_MASK);
1575
1576 if (unsignedLongCompare(estProduct, rs)) {
1577 qhat--;
1578 qrem = (int)((qrem & LONG_MASK) + dhLong);
1579 if ((qrem & LONG_MASK) >= dhLong) {
1580 estProduct -= (dl & LONG_MASK);
1581 rs = ((qrem & LONG_MASK) << 32) | nl;
1582 if (unsignedLongCompare(estProduct, rs))
1583 qhat--;
1584 }
1585 }
1586 }
1587
1588
1589 rem.value[j+rem.offset] = 0;
1590 int borrow = mulsub(rem.value, divisor, qhat, dlen, j+rem.offset);
1591
1592
1593 if (borrow + 0x80000000 > nh2) {
1594
1595 divadd(divisor, rem.value, j+1+rem.offset);
1596 qhat--;
1597 }
1598
1599
1600 q[j] = qhat;
1601 }
1602
1603
1604 int qhat = 0;
1605 int qrem = 0;
1606 boolean skipCorrection = false;
1607 int nh = rem.value[limit - 1 + rem.offset];
1608 int nh2 = nh + 0x80000000;
1609 int nm = rem.value[limit + rem.offset];
1610
1611 if (nh == dh) {
1612 qhat = ~0;
1613 qrem = nh + nm;
1614 skipCorrection = qrem + 0x80000000 < nh2;
1615 } else {
1616 long nChunk = (((long) nh) << 32) | (nm & LONG_MASK);
1617 if (nChunk >= 0) {
1618 qhat = (int) (nChunk / dhLong);
1619 qrem = (int) (nChunk - (qhat * dhLong));
1620 } else {
1621 long tmp = divWord(nChunk, dh);
1622 qhat = (int) (tmp & LONG_MASK);
1623 qrem = (int) (tmp >>> 32);
1624 }
1625 }
1626 if (qhat != 0) {
1627 if (!skipCorrection) {
1628 long nl = rem.value[limit + 1 + rem.offset] & LONG_MASK;
1629 long rs = ((qrem & LONG_MASK) << 32) | nl;
1630 long estProduct = (dl & LONG_MASK) * (qhat & LONG_MASK);
1631
1632 if (unsignedLongCompare(estProduct, rs)) {
1633 qhat--;
1634 qrem = (int) ((qrem & LONG_MASK) + dhLong);
1635 if ((qrem & LONG_MASK) >= dhLong) {
1636 estProduct -= (dl & LONG_MASK);
1637 rs = ((qrem & LONG_MASK) << 32) | nl;
1638 if (unsignedLongCompare(estProduct, rs))
1639 qhat--;
1640 }
1641 }
1642 }
1643
1644
1645
1646 int borrow;
1647 rem.value[limit - 1 + rem.offset] = 0;
1648 if(needRemainder)
1649 borrow = mulsub(rem.value, divisor, qhat, dlen, limit - 1 + rem.offset);
1650 else
1651 borrow = mulsubBorrow(rem.value, divisor, qhat, dlen, limit - 1 + rem.offset);
1652
1653
1654 if (borrow + 0x80000000 > nh2) {
1655
1656 if(needRemainder)
1657 divadd(divisor, rem.value, limit - 1 + 1 + rem.offset);
1658 qhat--;
1659 }
1660
1661
1662 q[(limit - 1)] = qhat;
1663 }
1664
1665
1666 if (needRemainder) {
1667
1668 if (shift > 0)
1669 rem.rightShift(shift);
1670 rem.normalize();
1671 }
1672 quotient.normalize();
1673 return needRemainder ? rem : null;
1674 }
1675
1676
1681 private MutableBigInteger divideLongMagnitude(long ldivisor, MutableBigInteger quotient) {
1682
1683 MutableBigInteger rem = new MutableBigInteger(new int[intLen + 1]);
1684 System.arraycopy(value, offset, rem.value, 1, intLen);
1685 rem.intLen = intLen;
1686 rem.offset = 1;
1687
1688 int nlen = rem.intLen;
1689
1690 int limit = nlen - 2 + 1;
1691 if (quotient.value.length < limit) {
1692 quotient.value = new int[limit];
1693 quotient.offset = 0;
1694 }
1695 quotient.intLen = limit;
1696 int[] q = quotient.value;
1697
1698
1699 int shift = Long.numberOfLeadingZeros(ldivisor);
1700 if (shift > 0) {
1701 ldivisor<<=shift;
1702 rem.leftShift(shift);
1703 }
1704
1705
1706 if (rem.intLen == nlen) {
1707 rem.offset = 0;
1708 rem.value[0] = 0;
1709 rem.intLen++;
1710 }
1711
1712 int dh = (int)(ldivisor >>> 32);
1713 long dhLong = dh & LONG_MASK;
1714 int dl = (int)(ldivisor & LONG_MASK);
1715
1716
1717 for (int j = 0; j < limit; j++) {
1718
1719
1720 int qhat = 0;
1721 int qrem = 0;
1722 boolean skipCorrection = false;
1723 int nh = rem.value[j + rem.offset];
1724 int nh2 = nh + 0x80000000;
1725 int nm = rem.value[j + 1 + rem.offset];
1726
1727 if (nh == dh) {
1728 qhat = ~0;
1729 qrem = nh + nm;
1730 skipCorrection = qrem + 0x80000000 < nh2;
1731 } else {
1732 long nChunk = (((long) nh) << 32) | (nm & LONG_MASK);
1733 if (nChunk >= 0) {
1734 qhat = (int) (nChunk / dhLong);
1735 qrem = (int) (nChunk - (qhat * dhLong));
1736 } else {
1737 long tmp = divWord(nChunk, dh);
1738 qhat =(int)(tmp & LONG_MASK);
1739 qrem = (int)(tmp>>>32);
1740 }
1741 }
1742
1743 if (qhat == 0)
1744 continue;
1745
1746 if (!skipCorrection) {
1747 long nl = rem.value[j + 2 + rem.offset] & LONG_MASK;
1748 long rs = ((qrem & LONG_MASK) << 32) | nl;
1749 long estProduct = (dl & LONG_MASK) * (qhat & LONG_MASK);
1750
1751 if (unsignedLongCompare(estProduct, rs)) {
1752 qhat--;
1753 qrem = (int) ((qrem & LONG_MASK) + dhLong);
1754 if ((qrem & LONG_MASK) >= dhLong) {
1755 estProduct -= (dl & LONG_MASK);
1756 rs = ((qrem & LONG_MASK) << 32) | nl;
1757 if (unsignedLongCompare(estProduct, rs))
1758 qhat--;
1759 }
1760 }
1761 }
1762
1763
1764 rem.value[j + rem.offset] = 0;
1765 int borrow = mulsubLong(rem.value, dh, dl, qhat, j + rem.offset);
1766
1767
1768 if (borrow + 0x80000000 > nh2) {
1769
1770 divaddLong(dh,dl, rem.value, j + 1 + rem.offset);
1771 qhat--;
1772 }
1773
1774
1775 q[j] = qhat;
1776 }
1777
1778
1779 if (shift > 0)
1780 rem.rightShift(shift);
1781
1782 quotient.normalize();
1783 rem.normalize();
1784 return rem;
1785 }
1786
1787
1792 private int divaddLong(int dh, int dl, int[] result, int offset) {
1793 long carry = 0;
1794
1795 long sum = (dl & LONG_MASK) + (result[1+offset] & LONG_MASK);
1796 result[1+offset] = (int)sum;
1797
1798 sum = (dh & LONG_MASK) + (result[offset] & LONG_MASK) + carry;
1799 result[offset] = (int)sum;
1800 carry = sum >>> 32;
1801 return (int)carry;
1802 }
1803
1804
1809 private int mulsubLong(int[] q, int dh, int dl, int x, int offset) {
1810 long xLong = x & LONG_MASK;
1811 offset += 2;
1812 long product = (dl & LONG_MASK) * xLong;
1813 long difference = q[offset] - product;
1814 q[offset--] = (int)difference;
1815 long carry = (product >>> 32)
1816 + (((difference & LONG_MASK) >
1817 (((~(int)product) & LONG_MASK))) ? 1:0);
1818 product = (dh & LONG_MASK) * xLong + carry;
1819 difference = q[offset] - product;
1820 q[offset--] = (int)difference;
1821 carry = (product >>> 32)
1822 + (((difference & LONG_MASK) >
1823 (((~(int)product) & LONG_MASK))) ? 1:0);
1824 return (int)carry;
1825 }
1826
1827
1831 private boolean unsignedLongCompare(long one, long two) {
1832 return (one+Long.MIN_VALUE) > (two+Long.MIN_VALUE);
1833 }
1834
1835
1842 static long divWord(long n, int d) {
1843 long dLong = d & LONG_MASK;
1844 long r;
1845 long q;
1846 if (dLong == 1) {
1847 q = (int)n;
1848 r = 0;
1849 return (r << 32) | (q & LONG_MASK);
1850 }
1851
1852
1853 q = (n >>> 1) / (dLong >>> 1);
1854 r = n - q*dLong;
1855
1856
1857 while (r < 0) {
1858 r += dLong;
1859 q--;
1860 }
1861 while (r >= dLong) {
1862 r -= dLong;
1863 q++;
1864 }
1865
1866 return (r << 32) | (q & LONG_MASK);
1867 }
1868
1869
1883 MutableBigInteger sqrt() {
1884
1885 if (this.isZero()) {
1886 return new MutableBigInteger(0);
1887 } else if (this.value.length == 1
1888 && (this.value[0] & LONG_MASK) < 4) {
1889 return ONE;
1890 }
1891
1892 if (bitLength() <= 63) {
1893
1894 long v = new BigInteger(this.value, 1).longValueExact();
1895 long xk = (long)Math.floor(Math.sqrt(v));
1896
1897
1898 do {
1899 long xk1 = (xk + v/xk)/2;
1900
1901
1902 if (xk1 >= xk) {
1903 return new MutableBigInteger(new int[] {
1904 (int)(xk >>> 32), (int)(xk & LONG_MASK)
1905 });
1906 }
1907
1908 xk = xk1;
1909 } while (true);
1910 } else {
1911
1912
1913
1914 int bitLength = (int) this.bitLength();
1915 if (bitLength != this.bitLength()) {
1916 throw new ArithmeticException("bitLength() integer overflow");
1917 }
1918
1919
1920 int shift = bitLength - 63;
1921 if (shift % 2 == 1) {
1922 shift++;
1923 }
1924
1925
1926 MutableBigInteger xk = new MutableBigInteger(this);
1927 xk.rightShift(shift);
1928 xk.normalize();
1929
1930
1931 double d = new BigInteger(xk.value, 1).doubleValue();
1932 BigInteger bi = BigInteger.valueOf((long)Math.ceil(Math.sqrt(d)));
1933 xk = new MutableBigInteger(bi.mag);
1934
1935
1936 xk.leftShift(shift / 2);
1937
1938
1939 MutableBigInteger xk1 = new MutableBigInteger();
1940 do {
1941
1942 this.divide(xk, xk1, false);
1943 xk1.add(xk);
1944 xk1.rightShift(1);
1945
1946
1947 if (xk1.compare(xk) >= 0) {
1948 return xk;
1949 }
1950
1951
1952 xk.copyValue(xk1);
1953
1954 xk1.reset();
1955 } while (true);
1956 }
1957 }
1958
1959
1962 MutableBigInteger hybridGCD(MutableBigInteger b) {
1963
1964
1965 MutableBigInteger a = this;
1966 MutableBigInteger q = new MutableBigInteger();
1967
1968 while (b.intLen != 0) {
1969 if (Math.abs(a.intLen - b.intLen) < 2)
1970 return a.binaryGCD(b);
1971
1972 MutableBigInteger r = a.divide(b, q);
1973 a = b;
1974 b = r;
1975 }
1976 return a;
1977 }
1978
1979
1983 private MutableBigInteger binaryGCD(MutableBigInteger v) {
1984
1985 MutableBigInteger u = this;
1986 MutableBigInteger r = new MutableBigInteger();
1987
1988
1989 int s1 = u.getLowestSetBit();
1990 int s2 = v.getLowestSetBit();
1991 int k = (s1 < s2) ? s1 : s2;
1992 if (k != 0) {
1993 u.rightShift(k);
1994 v.rightShift(k);
1995 }
1996
1997
1998 boolean uOdd = (k == s1);
1999 MutableBigInteger t = uOdd ? v: u;
2000 int tsign = uOdd ? -1 : 1;
2001
2002 int lb;
2003 while ((lb = t.getLowestSetBit()) >= 0) {
2004
2005 t.rightShift(lb);
2006
2007 if (tsign > 0)
2008 u = t;
2009 else
2010 v = t;
2011
2012
2013 if (u.intLen < 2 && v.intLen < 2) {
2014 int x = u.value[u.offset];
2015 int y = v.value[v.offset];
2016 x = binaryGcd(x, y);
2017 r.value[0] = x;
2018 r.intLen = 1;
2019 r.offset = 0;
2020 if (k > 0)
2021 r.leftShift(k);
2022 return r;
2023 }
2024
2025
2026 if ((tsign = u.difference(v)) == 0)
2027 break;
2028 t = (tsign >= 0) ? u : v;
2029 }
2030
2031 if (k > 0)
2032 u.leftShift(k);
2033 return u;
2034 }
2035
2036
2039 static int binaryGcd(int a, int b) {
2040 if (b == 0)
2041 return a;
2042 if (a == 0)
2043 return b;
2044
2045
2046 int aZeros = Integer.numberOfTrailingZeros(a);
2047 int bZeros = Integer.numberOfTrailingZeros(b);
2048 a >>>= aZeros;
2049 b >>>= bZeros;
2050
2051 int t = (aZeros < bZeros ? aZeros : bZeros);
2052
2053 while (a != b) {
2054 if ((a+0x80000000) > (b+0x80000000)) {
2055 a -= b;
2056 a >>>= Integer.numberOfTrailingZeros(a);
2057 } else {
2058 b -= a;
2059 b >>>= Integer.numberOfTrailingZeros(b);
2060 }
2061 }
2062 return a<<t;
2063 }
2064
2065
2069 MutableBigInteger mutableModInverse(MutableBigInteger p) {
2070
2071 if (p.isOdd())
2072 return modInverse(p);
2073
2074
2075 if (isEven())
2076 throw new ArithmeticException("BigInteger not invertible.");
2077
2078
2079 int powersOf2 = p.getLowestSetBit();
2080
2081
2082 MutableBigInteger oddMod = new MutableBigInteger(p);
2083 oddMod.rightShift(powersOf2);
2084
2085 if (oddMod.isOne())
2086 return modInverseMP2(powersOf2);
2087
2088
2089 MutableBigInteger oddPart = modInverse(oddMod);
2090
2091
2092 MutableBigInteger evenPart = modInverseMP2(powersOf2);
2093
2094
2095 MutableBigInteger y1 = modInverseBP2(oddMod, powersOf2);
2096 MutableBigInteger y2 = oddMod.modInverseMP2(powersOf2);
2097
2098 MutableBigInteger temp1 = new MutableBigInteger();
2099 MutableBigInteger temp2 = new MutableBigInteger();
2100 MutableBigInteger result = new MutableBigInteger();
2101
2102 oddPart.leftShift(powersOf2);
2103 oddPart.multiply(y1, result);
2104
2105 evenPart.multiply(oddMod, temp1);
2106 temp1.multiply(y2, temp2);
2107
2108 result.add(temp2);
2109 return result.divide(p, temp1);
2110 }
2111
2112
2115 MutableBigInteger modInverseMP2(int k) {
2116 if (isEven())
2117 throw new ArithmeticException("Non-invertible. (GCD != 1)");
2118
2119 if (k > 64)
2120 return euclidModInverse(k);
2121
2122 int t = inverseMod32(value[offset+intLen-1]);
2123
2124 if (k < 33) {
2125 t = (k == 32 ? t : t & ((1 << k) - 1));
2126 return new MutableBigInteger(t);
2127 }
2128
2129 long pLong = (value[offset+intLen-1] & LONG_MASK);
2130 if (intLen > 1)
2131 pLong |= ((long)value[offset+intLen-2] << 32);
2132 long tLong = t & LONG_MASK;
2133 tLong = tLong * (2 - pLong * tLong);
2134 tLong = (k == 64 ? tLong : tLong & ((1L << k) - 1));
2135
2136 MutableBigInteger result = new MutableBigInteger(new int[2]);
2137 result.value[0] = (int)(tLong >>> 32);
2138 result.value[1] = (int)tLong;
2139 result.intLen = 2;
2140 result.normalize();
2141 return result;
2142 }
2143
2144
2147 static int inverseMod32(int val) {
2148
2149 int t = val;
2150 t *= 2 - val*t;
2151 t *= 2 - val*t;
2152 t *= 2 - val*t;
2153 t *= 2 - val*t;
2154 return t;
2155 }
2156
2157
2160 static long inverseMod64(long val) {
2161
2162 long t = val;
2163 t *= 2 - val*t;
2164 t *= 2 - val*t;
2165 t *= 2 - val*t;
2166 t *= 2 - val*t;
2167 t *= 2 - val*t;
2168 assert(t * val == 1);
2169 return t;
2170 }
2171
2172
2175 static MutableBigInteger modInverseBP2(MutableBigInteger mod, int k) {
2176
2177 return fixup(new MutableBigInteger(1), new MutableBigInteger(mod), k);
2178 }
2179
2180
2189 private MutableBigInteger modInverse(MutableBigInteger mod) {
2190 MutableBigInteger p = new MutableBigInteger(mod);
2191 MutableBigInteger f = new MutableBigInteger(this);
2192 MutableBigInteger g = new MutableBigInteger(p);
2193 SignedMutableBigInteger c = new SignedMutableBigInteger(1);
2194 SignedMutableBigInteger d = new SignedMutableBigInteger();
2195 MutableBigInteger temp = null;
2196 SignedMutableBigInteger sTemp = null;
2197
2198 int k = 0;
2199
2200 if (f.isEven()) {
2201 int trailingZeros = f.getLowestSetBit();
2202 f.rightShift(trailingZeros);
2203 d.leftShift(trailingZeros);
2204 k = trailingZeros;
2205 }
2206
2207
2208 while (!f.isOne()) {
2209
2210 if (f.isZero())
2211 throw new ArithmeticException("BigInteger not invertible.");
2212
2213
2214 if (f.compare(g) < 0) {
2215 temp = f; f = g; g = temp;
2216 sTemp = d; d = c; c = sTemp;
2217 }
2218
2219
2220 if (((f.value[f.offset + f.intLen - 1] ^
2221 g.value[g.offset + g.intLen - 1]) & 3) == 0) {
2222 f.subtract(g);
2223 c.signedSubtract(d);
2224 } else {
2225 f.add(g);
2226 c.signedAdd(d);
2227 }
2228
2229
2230 int trailingZeros = f.getLowestSetBit();
2231 f.rightShift(trailingZeros);
2232 d.leftShift(trailingZeros);
2233 k += trailingZeros;
2234 }
2235
2236 while (c.sign < 0)
2237 c.signedAdd(p);
2238
2239 return fixup(c, p, k);
2240 }
2241
2242
2247 static MutableBigInteger fixup(MutableBigInteger c, MutableBigInteger p,
2248 int k) {
2249 MutableBigInteger temp = new MutableBigInteger();
2250
2251 int r = -inverseMod32(p.value[p.offset+p.intLen-1]);
2252
2253 for (int i=0, numWords = k >> 5; i < numWords; i++) {
2254
2255 int v = r * c.value[c.offset + c.intLen-1];
2256
2257 p.mul(v, temp);
2258 c.add(temp);
2259
2260 c.intLen--;
2261 }
2262 int numBits = k & 0x1f;
2263 if (numBits != 0) {
2264
2265 int v = r * c.value[c.offset + c.intLen-1];
2266 v &= ((1<<numBits) - 1);
2267
2268 p.mul(v, temp);
2269 c.add(temp);
2270
2271 c.rightShift(numBits);
2272 }
2273
2274
2275 while (c.compare(p) >= 0)
2276 c.subtract(p);
2277
2278 return c;
2279 }
2280
2281
2285 MutableBigInteger euclidModInverse(int k) {
2286 MutableBigInteger b = new MutableBigInteger(1);
2287 b.leftShift(k);
2288 MutableBigInteger mod = new MutableBigInteger(b);
2289
2290 MutableBigInteger a = new MutableBigInteger(this);
2291 MutableBigInteger q = new MutableBigInteger();
2292 MutableBigInteger r = b.divide(a, q);
2293
2294 MutableBigInteger swapper = b;
2295
2296 b = r;
2297 r = swapper;
2298
2299 MutableBigInteger t1 = new MutableBigInteger(q);
2300 MutableBigInteger t0 = new MutableBigInteger(1);
2301 MutableBigInteger temp = new MutableBigInteger();
2302
2303 while (!b.isOne()) {
2304 r = a.divide(b, q);
2305
2306 if (r.intLen == 0)
2307 throw new ArithmeticException("BigInteger not invertible.");
2308
2309 swapper = r;
2310 a = swapper;
2311
2312 if (q.intLen == 1)
2313 t1.mul(q.value[q.offset], temp);
2314 else
2315 q.multiply(t1, temp);
2316 swapper = q;
2317 q = temp;
2318 temp = swapper;
2319 t0.add(q);
2320
2321 if (a.isOne())
2322 return t0;
2323
2324 r = b.divide(a, q);
2325
2326 if (r.intLen == 0)
2327 throw new ArithmeticException("BigInteger not invertible.");
2328
2329 swapper = b;
2330 b = r;
2331
2332 if (q.intLen == 1)
2333 t0.mul(q.value[q.offset], temp);
2334 else
2335 q.multiply(t0, temp);
2336 swapper = q; q = temp; temp = swapper;
2337
2338 t1.add(q);
2339 }
2340 mod.subtract(t1);
2341 return mod;
2342 }
2343 }
2344