109 /** |
108 /** |
110 * Construct a new MutableBigInteger with a magnitude equal to the |
109 * Construct a new MutableBigInteger with a magnitude equal to the |
111 * specified BigInteger. |
110 * specified BigInteger. |
112 */ |
111 */ |
113 MutableBigInteger(BigInteger b) { |
112 MutableBigInteger(BigInteger b) { |
114 value = b.mag.clone(); |
113 intLen = b.mag.length; |
115 intLen = value.length; |
114 value = Arrays.copyOf(b.mag, intLen); |
116 } |
115 } |
117 |
116 |
118 /** |
117 /** |
119 * Construct a new MutableBigInteger with a magnitude equal to the |
118 * Construct a new MutableBigInteger with a magnitude equal to the |
120 * specified MutableBigInteger. |
119 * specified MutableBigInteger. |
121 */ |
120 */ |
122 MutableBigInteger(MutableBigInteger val) { |
121 MutableBigInteger(MutableBigInteger val) { |
123 intLen = val.intLen; |
122 intLen = val.intLen; |
124 value = new int[intLen]; |
123 value = Arrays.copyOfRange(val.value, val.offset, val.offset + intLen); |
125 |
124 } |
126 for(int i=0; i<intLen; i++) |
125 |
127 value[i] = val.value[val.offset+i]; |
126 /** |
|
127 * Internal helper method to return the magnitude array. The caller is not |
|
128 * supposed to modify the returned array. |
|
129 */ |
|
130 private int[] getMagnitudeArray() { |
|
131 if (offset > 0 || value.length != intLen) |
|
132 return Arrays.copyOfRange(value, offset, offset + intLen); |
|
133 return value; |
|
134 } |
|
135 |
|
136 /** |
|
137 * Convert this MutableBigInteger to a long value. The caller has to make |
|
138 * sure this MutableBigInteger can be fit into long. |
|
139 */ |
|
140 private long toLong() { |
|
141 assert (intLen <= 2) : "this MutableBigInteger exceeds the range of long"; |
|
142 if (intLen == 0) |
|
143 return 0; |
|
144 long d = value[offset] & LONG_MASK; |
|
145 return (intLen == 2) ? d << 32 | (value[offset + 1] & LONG_MASK) : d; |
|
146 } |
|
147 |
|
148 /** |
|
149 * Convert this MutableBigInteger to a BigInteger object. |
|
150 */ |
|
151 BigInteger toBigInteger(int sign) { |
|
152 if (intLen == 0 || sign == 0) |
|
153 return BigInteger.ZERO; |
|
154 return new BigInteger(getMagnitudeArray(), sign); |
|
155 } |
|
156 |
|
157 /** |
|
158 * Convert this MutableBigInteger to BigDecimal object with the specified sign |
|
159 * and scale. |
|
160 */ |
|
161 BigDecimal toBigDecimal(int sign, int scale) { |
|
162 if (intLen == 0 || sign == 0) |
|
163 return BigDecimal.valueOf(0, scale); |
|
164 int[] mag = getMagnitudeArray(); |
|
165 int len = mag.length; |
|
166 int d = mag[0]; |
|
167 // If this MutableBigInteger can't be fit into long, we need to |
|
168 // make a BigInteger object for the resultant BigDecimal object. |
|
169 if (len > 2 || (d < 0 && len == 2)) |
|
170 return new BigDecimal(new BigInteger(mag, sign), INFLATED, scale, 0); |
|
171 long v = (len == 2) ? |
|
172 ((mag[1] & LONG_MASK) | (d & LONG_MASK) << 32) : |
|
173 d & LONG_MASK; |
|
174 return new BigDecimal(null, sign == -1 ? -v : v, scale, 0); |
128 } |
175 } |
129 |
176 |
130 /** |
177 /** |
131 * Clear out a MutableBigInteger for reuse. |
178 * Clear out a MutableBigInteger for reuse. |
132 */ |
179 */ |
144 } |
191 } |
145 |
192 |
146 /** |
193 /** |
147 * Compare the magnitude of two MutableBigIntegers. Returns -1, 0 or 1 |
194 * Compare the magnitude of two MutableBigIntegers. Returns -1, 0 or 1 |
148 * as this MutableBigInteger is numerically less than, equal to, or |
195 * as this MutableBigInteger is numerically less than, equal to, or |
149 * greater than {@code b}. |
196 * greater than <tt>b</tt>. |
150 */ |
197 */ |
151 final int compare(MutableBigInteger b) { |
198 final int compare(MutableBigInteger b) { |
152 if (intLen < b.intLen) |
199 int blen = b.intLen; |
|
200 if (intLen < blen) |
153 return -1; |
201 return -1; |
154 if (intLen > b.intLen) |
202 if (intLen > blen) |
155 return 1; |
203 return 1; |
156 |
204 |
157 for (int i=0; i<intLen; i++) { |
205 // Add Integer.MIN_VALUE to make the comparison act as unsigned integer |
158 int b1 = value[offset+i] + 0x80000000; |
206 // comparison. |
159 int b2 = b.value[b.offset+i] + 0x80000000; |
207 int[] bval = b.value; |
|
208 for (int i = offset, j = b.offset; i < intLen + offset; i++, j++) { |
|
209 int b1 = value[i] + 0x80000000; |
|
210 int b2 = bval[j] + 0x80000000; |
160 if (b1 < b2) |
211 if (b1 < b2) |
161 return -1; |
212 return -1; |
162 if (b1 > b2) |
213 if (b1 > b2) |
163 return 1; |
214 return 1; |
164 } |
215 } |
165 return 0; |
216 return 0; |
|
217 } |
|
218 |
|
219 /** |
|
220 * Compare this against half of a MutableBigInteger object (Needed for |
|
221 * remainder tests). |
|
222 * Assumes no leading unnecessary zeros, which holds for results |
|
223 * from divide(). |
|
224 */ |
|
225 final int compareHalf(MutableBigInteger b) { |
|
226 int blen = b.intLen; |
|
227 int len = intLen; |
|
228 if (len <= 0) |
|
229 return blen <=0 ? 0 : -1; |
|
230 if (len > blen) |
|
231 return 1; |
|
232 if (len < blen - 1) |
|
233 return -1; |
|
234 int[] bval = b.value; |
|
235 int bstart = 0; |
|
236 int carry = 0; |
|
237 // Only 2 cases left:len == blen or len == blen - 1 |
|
238 if (len != blen) { // len == blen - 1 |
|
239 if (bval[bstart] == 1) { |
|
240 ++bstart; |
|
241 carry = 0x80000000; |
|
242 } else |
|
243 return -1; |
|
244 } |
|
245 // compare values with right-shifted values of b, |
|
246 // carrying shifted-out bits across words |
|
247 int[] val = value; |
|
248 for (int i = offset, j = bstart; i < len + offset;) { |
|
249 int bv = bval[j++]; |
|
250 long hb = ((bv >>> 1) + carry) & LONG_MASK; |
|
251 long v = val[i++] & LONG_MASK; |
|
252 if (v != hb) |
|
253 return v < hb ? -1 : 1; |
|
254 carry = (bv & 1) << 31; // carray will be either 0x80000000 or 0 |
|
255 } |
|
256 return carry == 0? 0 : -1; |
166 } |
257 } |
167 |
258 |
168 /** |
259 /** |
169 * Return the index of the lowest set bit in this MutableBigInteger. If the |
260 * Return the index of the lowest set bit in this MutableBigInteger. If the |
170 * magnitude of this MutableBigInteger is zero, -1 is returned. |
261 * magnitude of this MutableBigInteger is zero, -1 is returned. |
497 int y = addend.intLen; |
585 int y = addend.intLen; |
498 int resultLen = (intLen > addend.intLen ? intLen : addend.intLen); |
586 int resultLen = (intLen > addend.intLen ? intLen : addend.intLen); |
499 int[] result = (value.length < resultLen ? new int[resultLen] : value); |
587 int[] result = (value.length < resultLen ? new int[resultLen] : value); |
500 |
588 |
501 int rstart = result.length-1; |
589 int rstart = result.length-1; |
502 long sum = 0; |
590 long sum; |
|
591 long carry = 0; |
503 |
592 |
504 // Add common parts of both numbers |
593 // Add common parts of both numbers |
505 while(x>0 && y>0) { |
594 while(x>0 && y>0) { |
506 x--; y--; |
595 x--; y--; |
507 sum = (value[x+offset] & LONG_MASK) + |
596 sum = (value[x+offset] & LONG_MASK) + |
508 (addend.value[y+addend.offset] & LONG_MASK) + (sum >>> 32); |
597 (addend.value[y+addend.offset] & LONG_MASK) + carry; |
509 result[rstart--] = (int)sum; |
598 result[rstart--] = (int)sum; |
|
599 carry = sum >>> 32; |
510 } |
600 } |
511 |
601 |
512 // Add remainder of the longer number |
602 // Add remainder of the longer number |
513 while(x>0) { |
603 while(x>0) { |
514 x--; |
604 x--; |
515 sum = (value[x+offset] & LONG_MASK) + (sum >>> 32); |
605 if (carry == 0 && result == value && rstart == (x + offset)) |
|
606 return; |
|
607 sum = (value[x+offset] & LONG_MASK) + carry; |
516 result[rstart--] = (int)sum; |
608 result[rstart--] = (int)sum; |
|
609 carry = sum >>> 32; |
517 } |
610 } |
518 while(y>0) { |
611 while(y>0) { |
519 y--; |
612 y--; |
520 sum = (addend.value[y+addend.offset] & LONG_MASK) + (sum >>> 32); |
613 sum = (addend.value[y+addend.offset] & LONG_MASK) + carry; |
521 result[rstart--] = (int)sum; |
614 result[rstart--] = (int)sum; |
522 } |
615 carry = sum >>> 32; |
523 |
616 } |
524 if ((sum >>> 32) > 0) { // Result must grow in length |
617 |
|
618 if (carry > 0) { // Result must grow in length |
525 resultLen++; |
619 resultLen++; |
526 if (result.length < resultLen) { |
620 if (result.length < resultLen) { |
527 int temp[] = new int[resultLen]; |
621 int temp[] = new int[resultLen]; |
528 for (int i=resultLen-1; i>0; i--) |
622 // Result one word longer from carry-out; copy low-order |
529 temp[i] = result[i-1]; |
623 // bits into new result. |
|
624 System.arraycopy(result, 0, temp, 1, result.length); |
530 temp[0] = 1; |
625 temp[0] = 1; |
531 result = temp; |
626 result = temp; |
532 } else { |
627 } else { |
533 result[rstart--] = 1; |
628 result[rstart--] = 1; |
534 } |
629 } |
706 zval[0] = (int)carry; |
801 zval[0] = (int)carry; |
707 } |
802 } |
708 z.value = zval; |
803 z.value = zval; |
709 } |
804 } |
710 |
805 |
711 /** |
806 /** |
712 * This method is used for division of an n word dividend by a one word |
807 * This method is used for division of an n word dividend by a one word |
713 * divisor. The quotient is placed into quotient. The one word divisor is |
808 * divisor. The quotient is placed into quotient. The one word divisor is |
714 * specified by divisor. The value of this MutableBigInteger is the |
809 * specified by divisor. |
715 * dividend at invocation but is replaced by the remainder. |
|
716 * |
810 * |
717 * NOTE: The value of this MutableBigInteger is modified by this method. |
811 * @return the remainder of the division is returned. |
718 */ |
812 * |
719 void divideOneWord(int divisor, MutableBigInteger quotient) { |
813 */ |
720 long divLong = divisor & LONG_MASK; |
814 int divideOneWord(int divisor, MutableBigInteger quotient) { |
|
815 long divisorLong = divisor & LONG_MASK; |
721 |
816 |
722 // Special case of one word dividend |
817 // Special case of one word dividend |
723 if (intLen == 1) { |
818 if (intLen == 1) { |
724 long remValue = value[offset] & LONG_MASK; |
819 long dividendValue = value[offset] & LONG_MASK; |
725 quotient.value[0] = (int) (remValue / divLong); |
820 int q = (int) (dividendValue / divisorLong); |
726 quotient.intLen = (quotient.value[0] == 0) ? 0 : 1; |
821 int r = (int) (dividendValue - q * divisorLong); |
|
822 quotient.value[0] = q; |
|
823 quotient.intLen = (q == 0) ? 0 : 1; |
727 quotient.offset = 0; |
824 quotient.offset = 0; |
728 |
825 return r; |
729 value[0] = (int) (remValue - (quotient.value[0] * divLong)); |
|
730 offset = 0; |
|
731 intLen = (value[0] == 0) ? 0 : 1; |
|
732 |
|
733 return; |
|
734 } |
826 } |
735 |
827 |
736 if (quotient.value.length < intLen) |
828 if (quotient.value.length < intLen) |
737 quotient.value = new int[intLen]; |
829 quotient.value = new int[intLen]; |
738 quotient.offset = 0; |
830 quotient.offset = 0; |
739 quotient.intLen = intLen; |
831 quotient.intLen = intLen; |
740 |
832 |
741 // Normalize the divisor |
833 // Normalize the divisor |
742 int shift = 32 - BigInteger.bitLen(divisor); |
834 int shift = Integer.numberOfLeadingZeros(divisor); |
743 |
835 |
744 int rem = value[offset]; |
836 int rem = value[offset]; |
745 long remLong = rem & LONG_MASK; |
837 long remLong = rem & LONG_MASK; |
746 if (remLong < divLong) { |
838 if (remLong < divisorLong) { |
747 quotient.value[0] = 0; |
839 quotient.value[0] = 0; |
748 } else { |
840 } else { |
749 quotient.value[0] = (int)(remLong/divLong); |
841 quotient.value[0] = (int)(remLong / divisorLong); |
750 rem = (int) (remLong - (quotient.value[0] * divLong)); |
842 rem = (int) (remLong - (quotient.value[0] * divisorLong)); |
751 remLong = rem & LONG_MASK; |
843 remLong = rem & LONG_MASK; |
752 } |
844 } |
753 |
845 |
754 int xlen = intLen; |
846 int xlen = intLen; |
755 int[] qWord = new int[2]; |
847 int[] qWord = new int[2]; |
756 while (--xlen > 0) { |
848 while (--xlen > 0) { |
757 long dividendEstimate = (remLong<<32) | |
849 long dividendEstimate = (remLong<<32) | |
758 (value[offset + intLen - xlen] & LONG_MASK); |
850 (value[offset + intLen - xlen] & LONG_MASK); |
759 if (dividendEstimate >= 0) { |
851 if (dividendEstimate >= 0) { |
760 qWord[0] = (int) (dividendEstimate/divLong); |
852 qWord[0] = (int) (dividendEstimate / divisorLong); |
761 qWord[1] = (int) (dividendEstimate - (qWord[0] * divLong)); |
853 qWord[1] = (int) (dividendEstimate - qWord[0] * divisorLong); |
762 } else { |
854 } else { |
763 divWord(qWord, dividendEstimate, divisor); |
855 divWord(qWord, dividendEstimate, divisor); |
764 } |
856 } |
765 quotient.value[intLen - xlen] = qWord[0]; |
857 quotient.value[intLen - xlen] = qWord[0]; |
766 rem = qWord[1]; |
858 rem = qWord[1]; |
767 remLong = rem & LONG_MASK; |
859 remLong = rem & LONG_MASK; |
768 } |
860 } |
769 |
861 |
|
862 quotient.normalize(); |
770 // Unnormalize |
863 // Unnormalize |
771 if (shift > 0) |
864 if (shift > 0) |
772 value[0] = rem %= divisor; |
865 return rem % divisor; |
773 else |
866 else |
774 value[0] = rem; |
867 return rem; |
775 intLen = (value[0] == 0) ? 0 : 1; |
868 } |
776 |
869 |
777 quotient.normalize(); |
870 /** |
778 } |
871 * Calculates the quotient of this div b and places the quotient in the |
779 |
872 * provided MutableBigInteger objects and the remainder object is returned. |
780 |
|
781 /** |
|
782 * Calculates the quotient and remainder of this div b and places them |
|
783 * in the MutableBigInteger objects provided. |
|
784 * |
873 * |
785 * Uses Algorithm D in Knuth section 4.3.1. |
874 * Uses Algorithm D in Knuth section 4.3.1. |
786 * Many optimizations to that algorithm have been adapted from the Colin |
875 * Many optimizations to that algorithm have been adapted from the Colin |
787 * Plumb C library. |
876 * Plumb C library. |
788 * It special cases one word divisors for speed. |
877 * It special cases one word divisors for speed. The content of b is not |
789 * The contents of a and b are not changed. |
878 * changed. |
790 * |
879 * |
791 */ |
880 */ |
792 void divide(MutableBigInteger b, |
881 MutableBigInteger divide(MutableBigInteger b, MutableBigInteger quotient) { |
793 MutableBigInteger quotient, MutableBigInteger rem) { |
|
794 if (b.intLen == 0) |
882 if (b.intLen == 0) |
795 throw new ArithmeticException("BigInteger divide by zero"); |
883 throw new ArithmeticException("BigInteger divide by zero"); |
796 |
884 |
797 // Dividend is zero |
885 // Dividend is zero |
798 if (intLen == 0) { |
886 if (intLen == 0) { |
799 quotient.intLen = quotient.offset = rem.intLen = rem.offset = 0; |
887 quotient.intLen = quotient.offset; |
800 return; |
888 return new MutableBigInteger(); |
801 } |
889 } |
802 |
890 |
803 int cmp = compare(b); |
891 int cmp = compare(b); |
804 |
|
805 // Dividend less than divisor |
892 // Dividend less than divisor |
806 if (cmp < 0) { |
893 if (cmp < 0) { |
807 quotient.intLen = quotient.offset = 0; |
894 quotient.intLen = quotient.offset = 0; |
808 rem.copyValue(this); |
895 return new MutableBigInteger(this); |
809 return; |
|
810 } |
896 } |
811 // Dividend equal to divisor |
897 // Dividend equal to divisor |
812 if (cmp == 0) { |
898 if (cmp == 0) { |
813 quotient.value[0] = quotient.intLen = 1; |
899 quotient.value[0] = quotient.intLen = 1; |
814 quotient.offset = rem.intLen = rem.offset = 0; |
900 quotient.offset = 0; |
815 return; |
901 return new MutableBigInteger(); |
816 } |
902 } |
817 |
903 |
818 quotient.clear(); |
904 quotient.clear(); |
819 |
|
820 // Special case one word divisor |
905 // Special case one word divisor |
821 if (b.intLen == 1) { |
906 if (b.intLen == 1) { |
822 rem.copyValue(this); |
907 int r = divideOneWord(b.value[b.offset], quotient); |
823 rem.divideOneWord(b.value[b.offset], quotient); |
908 if (r == 0) |
824 return; |
909 return new MutableBigInteger(); |
|
910 return new MutableBigInteger(r); |
825 } |
911 } |
826 |
912 |
827 // Copy divisor value to protect divisor |
913 // Copy divisor value to protect divisor |
828 int[] d = new int[b.intLen]; |
914 int[] div = Arrays.copyOfRange(b.value, b.offset, b.offset + b.intLen); |
829 for(int i=0; i<b.intLen; i++) |
915 return divideMagnitude(div, quotient); |
830 d[i] = b.value[b.offset+i]; |
916 } |
831 int dlen = b.intLen; |
917 |
|
918 /** |
|
919 * Internally used to calculate the quotient of this div v and places the |
|
920 * quotient in the provided MutableBigInteger object and the remainder is |
|
921 * returned. |
|
922 * |
|
923 * @return the remainder of the division will be returned. |
|
924 */ |
|
925 long divide(long v, MutableBigInteger quotient) { |
|
926 if (v == 0) |
|
927 throw new ArithmeticException("BigInteger divide by zero"); |
|
928 |
|
929 // Dividend is zero |
|
930 if (intLen == 0) { |
|
931 quotient.intLen = quotient.offset = 0; |
|
932 return 0; |
|
933 } |
|
934 if (v < 0) |
|
935 v = -v; |
|
936 |
|
937 int d = (int)(v >>> 32); |
|
938 quotient.clear(); |
|
939 // Special case on word divisor |
|
940 if (d == 0) |
|
941 return divideOneWord((int)v, quotient) & LONG_MASK; |
|
942 else { |
|
943 int[] div = new int[]{ d, (int)(v & LONG_MASK) }; |
|
944 return divideMagnitude(div, quotient).toLong(); |
|
945 } |
|
946 } |
|
947 |
|
948 /** |
|
949 * Divide this MutableBigInteger by the divisor represented by its magnitude |
|
950 * array. The quotient will be placed into the provided quotient object & |
|
951 * the remainder object is returned. |
|
952 */ |
|
953 private MutableBigInteger divideMagnitude(int[] divisor, |
|
954 MutableBigInteger quotient) { |
832 |
955 |
833 // Remainder starts as dividend with space for a leading zero |
956 // Remainder starts as dividend with space for a leading zero |
834 if (rem.value.length < intLen +1) |
957 MutableBigInteger rem = new MutableBigInteger(new int[intLen + 1]); |
835 rem.value = new int[intLen+1]; |
958 System.arraycopy(value, offset, rem.value, 1, intLen); |
836 |
|
837 for (int i=0; i<intLen; i++) |
|
838 rem.value[i+1] = value[i+offset]; |
|
839 rem.intLen = intLen; |
959 rem.intLen = intLen; |
840 rem.offset = 1; |
960 rem.offset = 1; |
841 |
961 |
842 int nlen = rem.intLen; |
962 int nlen = rem.intLen; |
843 |
963 |
844 // Set the quotient size |
964 // Set the quotient size |
|
965 int dlen = divisor.length; |
845 int limit = nlen - dlen + 1; |
966 int limit = nlen - dlen + 1; |
846 if (quotient.value.length < limit) { |
967 if (quotient.value.length < limit) { |
847 quotient.value = new int[limit]; |
968 quotient.value = new int[limit]; |
848 quotient.offset = 0; |
969 quotient.offset = 0; |
849 } |
970 } |
850 quotient.intLen = limit; |
971 quotient.intLen = limit; |
851 int[] q = quotient.value; |
972 int[] q = quotient.value; |
852 |
973 |
853 // D1 normalize the divisor |
974 // D1 normalize the divisor |
854 int shift = 32 - BigInteger.bitLen(d[0]); |
975 int shift = Integer.numberOfLeadingZeros(divisor[0]); |
855 if (shift > 0) { |
976 if (shift > 0) { |
856 // First shift will not grow array |
977 // First shift will not grow array |
857 BigInteger.primitiveLeftShift(d, dlen, shift); |
978 BigInteger.primitiveLeftShift(divisor, dlen, shift); |
858 // But this one might |
979 // But this one might |
859 rem.leftShift(shift); |
980 rem.leftShift(shift); |
860 } |
981 } |
861 |
982 |
862 // Must insert leading 0 in rem if its length did not change |
983 // Must insert leading 0 in rem if its length did not change |