Skip to content

Commit 990e745

Browse files
hansonrhansonr
authored andcommitted
adds test.math; fixes BigInteger;working
1 parent 40ae205 commit 990e745

14 files changed

+13641
-96
lines changed

sources/net.sf.j2s.java.core/src/java/math/BigInteger.java

Lines changed: 107 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)