@@ -371,7 +371,7 @@ private boolean isOneInt() {
371371 * of ints in the divisor are larger than this value, Burnikel-Ziegler
372372 * division may be used. This value is found experimentally to work well.
373373 */
374- static final int BURNIKEL_ZIEGLER_THRESHOLD = 0 ; // 80;
374+ static final int BURNIKEL_ZIEGLER_THRESHOLD = 80 ;
375375
376376 /**
377377 * The offset value for using Burnikel-Ziegler division. If the number
@@ -380,7 +380,7 @@ private boolean isOneInt() {
380380 * divisor plus this value, Burnikel-Ziegler division will be used. This
381381 * value is found experimentally to work well.
382382 */
383- static final int BURNIKEL_ZIEGLER_OFFSET = 0 ; // 40;
383+ static final int BURNIKEL_ZIEGLER_OFFSET = 40 ;
384384
385385 /**
386386 * The threshold value for using Schoenhage recursive base conversion. If
@@ -684,20 +684,26 @@ public BigInteger(String val, int radix) {
684684 int [] magnitude = new int [numWords ];
685685
686686 // Process first (potentially short) digit group
687- int firstGroupLen = numDigits % digitsPerInt [radix ];
687+ int firstGroupLen = numDigits % digitsPerInt24 [radix ];
688688 if (firstGroupLen == 0 )
689- firstGroupLen = digitsPerInt [radix ];
689+ firstGroupLen = digitsPerInt24 [radix ];
690690 String group = val .substring (cursor , cursor += firstGroupLen );
691691 int n = Integer .parseInt (group , radix );
692692 if (magnitude [numWords - 1 ] < 0 )
693693 throw new NumberFormatException ("Illegal digit" );
694+
695+
696+
694697 magnitude [numWords - 1 ] = (int ) getLowBits (n );
695698 magnitude [numWords - 2 ] = (int ) getHighBits (n );
699+
700+
701+
696702 // Process remaining digit groups
697- int superRadix = intRadix [radix ];
703+ int superRadix = intRadix24 [radix ];
698704 int groupVal = 0 ;
699705 while (cursor < len ) {
700- group = val .substring (cursor , cursor += digitsPerInt [radix ]);
706+ group = val .substring (cursor , cursor += digitsPerInt24 [radix ]);
701707 groupVal = Integer .parseInt (group , radix );
702708 if (groupVal < 0 )
703709 throw new NumberFormatException ("Illegal digit" );
@@ -744,15 +750,15 @@ public BigInteger(String val, int radix) {
744750 int [] magnitude = new int [numWords ];
745751
746752 // Process first (potentially short) digit group
747- int firstGroupLen = numDigits % digitsPerInt [10 ];
753+ int firstGroupLen = numDigits % digitsPerInt24 [10 ];
748754 if (firstGroupLen == 0 )
749- firstGroupLen = digitsPerInt [10 ];
755+ firstGroupLen = digitsPerInt24 [10 ];
750756 magnitude [numWords - 1 ] = parseInt (val , cursor , cursor += firstGroupLen );
751757
752758 // Process remaining digit groups
753759 while (cursor < len ) {
754- int groupVal = parseInt (val , cursor , cursor += digitsPerInt [10 ]);
755- destructiveMulAdd (magnitude , intRadix [10 ], groupVal );
760+ int groupVal = parseInt (val , cursor , cursor += digitsPerInt24 [10 ]);
761+ destructiveMulAdd (magnitude , intRadix24 [10 ], groupVal );
756762 }
757763 mag = trustedStripLeadingZeroInts (magnitude );
758764 if (mag .length >= MAX_MAG_LENGTH ) {
@@ -786,14 +792,13 @@ private int parseInt(char[] source, int start, int end) {
786792 4696 , 4756 , 4814 , 4870 , 4923 , 4975 , 5025 , 5074 , 5120 , 5166 , 5210 ,
787793 5253 , 5295 };
788794
789- // Multiply x array times word y in place, and add word z
795+ // Multiply x array times word y in place, and add word groupVal
790796 private static void destructiveMulAdd (int [] x , int y , int groupVal ) {
791797 // Perform the multiplication word by word
792798 long ylow = getLowBits (y );
793799 long zlong = getLowBits (groupVal );// SwingJS TODO can a radix group val be so large?
794- long yhigh = getHighBits (y );
795800 int len = x .length ;
796- int [] x2 = Arrays .copyOf (x , x .length );
801+ // int[] x2 = Arrays.copyOf(x, x.length);
797802 long product = 0 ;
798803 long carry = 0 ;
799804 long carry2 = 0 ;
@@ -802,17 +807,19 @@ private static void destructiveMulAdd(int[] x, int y, int groupVal) {
802807 product = ylow * getLowBits (x [i ]) + carry ;
803808 x [i ] = (int )getLowBits (product );
804809 carry = getHighBits (product );
805- product2 = yhigh * getLowBits (x2 [i ]) + carry2 ;
806- x2 [i ] = (int )getLowBits (product2 );
807- carry2 = getHighBits (product2 );
810+ // product2 = yhigh * getLowBits(x2[i]) + carry2;
811+ // x2[i] = (int)getLowBits(product2);
812+ // carry2 = getHighBits(product2);
808813 }
809814
810815 // Perform the addition
811816 long sum = getLowBits (x [len -1 ]) + zlong ;
812817 x [len -1 ] = (int )getLowBits (sum );
813818 carry = getHighBits (sum );
814819 for (int i = len -2 ; i >= 0 ; i --) {
815- sum = getLowBits (x [i ]) + getLowBits (x2 [i + 1 ]) + carry ;
820+ sum = getLowBits (x [i ])
821+ //+ getLowBits(x2[i + 1])
822+ + carry ;
816823 x [i ] = (int )getLowBits (sum );
817824 carry = getHighBits (sum );
818825 }
@@ -1760,6 +1767,9 @@ private int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
17601767 int xstart = xlen - 1 ;
17611768 int ystart = ylen - 1 ;
17621769
1770+ // dumpBits(x, "mul0x");
1771+ // dumpBits(y, "mul0y");
1772+ //
17631773 if (z == null || z .length < (xlen + ylen ))
17641774 z = new int [xlen +ylen ];
17651775
@@ -1769,9 +1779,10 @@ private int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
17691779 getLowBits (x [xstart ]) + carry ;
17701780 z [k ] = (int )getLowBits (product );
17711781 carry = getHighBits (product );
1782+ // System.out.println("product " + product + " carry " + carry);
1783+ // dumpBits(z, "mul ijk=" + xstart + " " + j + " " + k );
17721784 }
17731785 z [xstart ] = (int )carry ;
1774-
17751786 for (int i = xstart -1 ; i >= 0 ; i --) {
17761787 carry = 0 ;
17771788 for (int j =ystart , k =ystart +1 +i ; j >= 0 ; j --, k --) {
@@ -1780,13 +1791,17 @@ private int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
17801791 getLowBits (z [k ]) + carry ;
17811792 z [k ] = (int )getLowBits (product );
17821793 carry = getHighBits (product );
1794+ // System.out.println("product " + product + " carry " + carry);
1795+ // dumpBits(z, "mul1 ijk=" + i + " " + j + " " + k);
17831796 }
17841797 z [i ] = (int )carry ;
1798+ // System.out.println("z" + i + " = " + carry);
17851799 }
1800+ // dumpBits(z, "mul1");
17861801 return z ;
17871802 }
17881803
1789- /**
1804+ /**
17901805 * Multiplies two BigIntegers using the Karatsuba multiplication
17911806 * algorithm. This is a recursive divide-and-conquer algorithm which is
17921807 * more efficient for large numbers than what is commonly called the
@@ -3917,17 +3932,25 @@ public String toString() {
39173932 return toString (10 );
39183933 }
39193934
3920- void dumpBits () {
3921- System .out .println ("js bigint:" );
3922- for (int i = 0 ; i < mag .length ; i ++) {
3923- String s = "00000000000000000000000000000000000000000000000000000000000000000000" + Integer .toBinaryString (mag [i ]);
3935+ void dumpBits (int [] val , String msg ) {
3936+ if (val == null )
3937+ val = mag ;
3938+ System .out .println ("js bigint:" + msg );
3939+ for (int i = 0 ; i < val .length ; i ++) {
3940+ String s = "00000000000000000000000000000000000000000000000000000000000000000000" + Integer .toBinaryString (val [i ]);
39243941 s = s .substring (s .length () - 32 );
39253942 for (int j = 0 ; j < 32 ; j += 8 )
39263943 System .out .print (s .substring (j , j +8 ) + " " );
39273944 System .out .println ("" );
39283945 }
39293946 }
39303947
3948+
3949+ void dumpBits () {
3950+ dumpBits (null , "mag" );
3951+ }
3952+
3953+
39313954 /**
39323955 * Returns a byte array containing the two's-complement
39333956 * representation of this BigInteger. The byte array will be in
@@ -4504,13 +4527,17 @@ private static int[] makePositive(int a[]) {
45044527 /*
45054528 * These two arrays are the integer analogue of above.
45064529 */
4507- private static int digitsPerInt [] = {0 , 0 ,
4508- // 2 4 6 8 10 12 14 16 18
4509- 30 , 19 , 15 , 13 , 11 , 11 , 10 , 9 , 9 , 8 , 8 , 8 , 8 , 7 , 7 , 7 , 7 , 7 ,
4510- // 20 22 2 26 28 30 32 34 36
4511- 7 , 7 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 5 };
4512-
4513- private static int intRadix [] = {0 , 0 ,
4530+ private static int digitsPerInt32 [] = {0 , 0 ,
4531+ /* 2 */ 30 , /* 3 */ 19 , /* 4 */ 15 , /* 5 */ 13 , /* 6 */ 11 ,
4532+ /* 7 */ 11 , /* 8 */ 10 , /* 9 */ 9 , /* 10 */ 9 , /* 11 */ 8 ,
4533+ /* 12 */ 8 , /* 13 */ 8 , /* 14 */ 8 , /* 15 */ 7 , /* 16 */ 7 ,
4534+ /* 17 */ 7 , /* 18 */ 7 , /* 19 */ 7 , /* 20 */ 7 , /* 21 */ 7 ,
4535+ /* 22 */ 6 , /* 23 */ 6 , /* 24 */ 6 , /* 25 */ 6 , /* 26 */ 6 ,
4536+ /* 27 */ 6 , /* 28 */ 6 , /* 29 */ 6 , /* 30 */ 6 , /* 31 */ 6 ,
4537+ /* 32 */ 6 , /* 33 */ 6 , /* 34 */ 6 , /* 35 */ 6 , /* 36 */ 5 ,
4538+ };
4539+
4540+ private static int intRadix32 [] = {0 , 0 ,
45144541 0x40000000 , 0x4546b3db , 0x40000000 , 0x48c27395 , 0x159fd800 ,
45154542 0x75db9c97 , 0x40000000 , 0x17179149 , 0x3b9aca00 , 0xcc6db61 ,
45164543 0x19a10000 , 0x309f1021 , 0x57f6c100 , 0xa2f1b6f , 0x10000000 ,
@@ -4520,6 +4547,56 @@ private static int[] makePositive(int a[]) {
45204547 0x40000000 , 0x4cfa3cc1 , 0x5c13d840 , 0x6d91b519 , 0x39aa400
45214548 };
45224549
4550+
4551+ private static int digitsPerInt24 [] = {0 , 0 ,
4552+ /* 2 */ 23 , /* 3 */ 15 , /* 4 */ 11 , /* 5 */ 10 , /* 6 */ 9 ,
4553+ /* 7 */ 8 , /* 8 */ 7 , /* 9 */ 7 , /* 10 */ 7 , /* 11 */ 6 ,
4554+ /* 12 */ 6 , /* 13 */ 6 , /* 14 */ 6 , /* 15 */ 6 , /* 16 */ 5 ,
4555+ /* 17 */ 5 , /* 18 */ 5 , /* 19 */ 5 , /* 20 */ 5 , /* 21 */ 5 ,
4556+ /* 22 */ 5 , /* 23 */ 5 , /* 24 */ 5 , /* 25 */ 5 , /* 26 */ 5 ,
4557+ /* 27 */ 5 , /* 28 */ 4 , /* 29 */ 4 , /* 30 */ 4 , /* 31 */ 4 ,
4558+ /* 32 */ 4 , /* 33 */ 4 , /* 34 */ 4 , /* 35 */ 4 , /* 36 */ 4 ,
4559+ };
4560+
4561+ private static int intRadix24 [] = {0 , 0 ,
4562+ /* 2 */ 0x800000 ,
4563+ /* 3 */ 0xdaf26b ,
4564+ /* 4 */ 0x400000 ,
4565+ /* 5 */ 0x9502f9 ,
4566+ /* 6 */ 0x99c600 ,
4567+ /* 7 */ 0x57f6c1 ,
4568+ /* 8 */ 0x200000 ,
4569+ /* 9 */ 0x48fb79 ,
4570+ /* 10 */ 0x989680 ,
4571+ /* 11 */ 0x1b0829 ,
4572+ /* 12 */ 0x2d9000 ,
4573+ /* 13 */ 0x49a6b9 ,
4574+ /* 14 */ 0x72e440 ,
4575+ /* 15 */ 0xadcea1 ,
4576+ /* 16 */ 0x100000 ,
4577+ /* 17 */ 0x15aa51 ,
4578+ /* 18 */ 0x1cd520 ,
4579+ /* 19 */ 0x25c843 ,
4580+ /* 20 */ 0x30d400 ,
4581+ /* 21 */ 0x3e5185 ,
4582+ /* 22 */ 0x4ea360 ,
4583+ /* 23 */ 0x6235f7 ,
4584+ /* 24 */ 0x798000 ,
4585+ /* 25 */ 0x9502f9 ,
4586+ /* 26 */ 0xb54ba0 ,
4587+ /* 27 */ 0xdaf26b ,
4588+ /* 28 */ 0x96100 ,
4589+ /* 29 */ 0xacad1 ,
4590+ /* 30 */ 0xc5c10 ,
4591+ /* 31 */ 0xe1781 ,
4592+ /* 32 */ 0x100000 ,
4593+ /* 33 */ 0x121881 ,
4594+ /* 34 */ 0x146410 ,
4595+ /* 35 */ 0x16e5d1 ,
4596+ /* 36 */ 0x19a100 ,
4597+ };
4598+
4599+
45234600 /**
45244601 * These routines provide access to the two's complement representation
45254602 * of BigIntegers.
0 commit comments