Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a826557

Browse files
committed
fixes MutableBigInteger (mostly for BigDecimal) not set to roll over
integer on overflow. issue #270 and related
1 parent 8d78ad0 commit a826557

File tree

2 files changed

+56
-39
lines changed

2 files changed

+56
-39
lines changed

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

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
/*
2+
* 2024.02.21 BH modified for SwingJS with a few (more!) (x + 0x80000000)|0 adjustments
3+
*
24
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
35
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
46
*
@@ -25,7 +27,7 @@
2527

2628
package java.math;
2729

28-
/**
30+
/**
2931
* A class used to represent multiprecision integers that makes efficient
3032
* use of allocated space by allowing a number to occupy only part of
3133
* an array so that the arrays do not have to be reallocated as often.
@@ -294,8 +296,8 @@ private int compareShifted(MutableBigInteger b, int ints) {
294296
// comparison.
295297
int[] bval = b.value;
296298
for (int i = offset, j = b.offset; i < alen + offset; i++, j++) {
297-
int b1 = value[i] + 0x80000000;
298-
int b2 = bval[j] + 0x80000000;
299+
int b1 = (value[i] + 0x80000000)| 0;
300+
int b2 = (bval[j] + 0x80000000)| 0;
299301
if (b1 < b2)
300302
return -1;
301303
if (b1 > b2)
@@ -339,7 +341,7 @@ final int compareHalf(MutableBigInteger b) {
339341
long v = val[i++] & LONG_MASK;
340342
if (v != hb)
341343
return v < hb ? -1 : 1;
342-
carry = (bv & 1) << 31; // carray will be either 0x80000000 or 0
344+
carry = ((bv & 1) << 31)|0; // carray will be either 0x80000000 or 0
343345
}
344346
return carry == 0 ? 0 : -1;
345347
}
@@ -1131,7 +1133,6 @@ int divideOneWord(int divisor, MutableBigInteger quotient) {
11311133
quotient.value[intLen - xlen] = q;
11321134
remLong = rem & LONG_MASK;
11331135
}
1134-
11351136
quotient.normalize();
11361137
// Unnormalize
11371138
if (shift > 0)
@@ -1362,8 +1363,7 @@ private MutableBigInteger divide3n2n(MutableBigInteger b, MutableBigInteger quot
13621363
if (compareShifted(b, n) < 0) {
13631364
// step 3a: if a1<b1, let quotient=a12/b1 and r=a12%b1
13641365
r = a12.divide2n1n(b1, quotient);
1365-
1366-
// step 4: d=quotient*b2
1366+
// step 4: d=quotient*b2
13671367
d = new MutableBigInteger(quotient.toBigInteger().multiply(b2));
13681368
} else {
13691369
// step 3b: if a1>=b1, let quotient=beta^n-1 and r=a12-b1*2^n+b1
@@ -1378,7 +1378,7 @@ private MutableBigInteger divide3n2n(MutableBigInteger b, MutableBigInteger quot
13781378
d.leftShift(32 * n);
13791379
d.subtract(new MutableBigInteger(b2));
13801380
}
1381-
1381+
13821382
// step 5: r = r*beta^n + a3 - d (paper says a4)
13831383
// However, don't subtract d until after the while loop so r doesn't become negative
13841384
r.leftShift(32 * n);
@@ -1548,13 +1548,13 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
15481548
int qrem = 0;
15491549
boolean skipCorrection = false;
15501550
int nh = rem.value[j+rem.offset];
1551-
int nh2 = nh + 0x80000000;
1551+
int nh2 = (nh + 0x80000000)| 0;
15521552
int nm = rem.value[j+1+rem.offset];
15531553

15541554
if (nh == dh) {
15551555
qhat = ~0;
15561556
qrem = nh + nm;
1557-
skipCorrection = qrem + 0x80000000 < nh2;
1557+
skipCorrection = ((qrem + 0x80000000)| 0) < nh2;
15581558
} else {
15591559
long nChunk = (((long)nh) << 32) | (nm & LONG_MASK);
15601560
if (nChunk >= 0) {
@@ -1607,13 +1607,13 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
16071607
int qrem = 0;
16081608
boolean skipCorrection = false;
16091609
int nh = rem.value[limit - 1 + rem.offset];
1610-
int nh2 = nh + 0x80000000;
1610+
int nh2 = (nh + 0x80000000)|0;
16111611
int nm = rem.value[limit + rem.offset];
16121612

16131613
if (nh == dh) {
16141614
qhat = ~0;
16151615
qrem = nh + nm;
1616-
skipCorrection = qrem + 0x80000000 < nh2;
1616+
skipCorrection = ((qrem + 0x80000000)|0) < nh2;
16171617
} else {
16181618
long nChunk = (((long) nh) << 32) | (nm & LONG_MASK);
16191619
if (nChunk >= 0) {
@@ -1653,7 +1653,7 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
16531653
borrow = mulsubBorrow(rem.value, divisor, qhat, dlen, limit - 1 + rem.offset);
16541654

16551655
// D5 Test remainder
1656-
if (borrow + 0x80000000 > nh2) {
1656+
if (((borrow + 0x80000000)|0) > nh2) {
16571657
// D6 Add back
16581658
if(needRemainder)
16591659
divadd(divisor, rem.value, limit - 1 + 1 + rem.offset);
@@ -1723,13 +1723,13 @@ private MutableBigInteger divideLongMagnitude(long ldivisor, MutableBigInteger q
17231723
int qrem = 0;
17241724
boolean skipCorrection = false;
17251725
int nh = rem.value[j + rem.offset];
1726-
int nh2 = nh + 0x80000000;
1726+
int nh2 = (nh + 0x80000000)|0;
17271727
int nm = rem.value[j + 1 + rem.offset];
17281728

17291729
if (nh == dh) {
17301730
qhat = ~0;
17311731
qrem = nh + nm;
1732-
skipCorrection = qrem + 0x80000000 < nh2;
1732+
skipCorrection = ((qrem + 0x80000000)|0) < nh2;
17331733
} else {
17341734
long nChunk = (((long) nh) << 32) | (nm & LONG_MASK);
17351735
if (nChunk >= 0) {
@@ -1767,7 +1767,7 @@ private MutableBigInteger divideLongMagnitude(long ldivisor, MutableBigInteger q
17671767
int borrow = mulsubLong(rem.value, dh, dl, qhat, j + rem.offset);
17681768

17691769
// D5 Test remainder
1770-
if (borrow + 0x80000000 > nh2) {
1770+
if (((borrow + 0x80000000)|0) > nh2) {
17711771
// D6 Add back
17721772
divaddLong(dh,dl, rem.value, j + 1 + rem.offset);
17731773
qhat--;
@@ -1963,7 +1963,7 @@ static int binaryGcd(int a, int b) {
19631963
int t = (aZeros < bZeros ? aZeros : bZeros);
19641964

19651965
while (a != b) {
1966-
if ((a+0x80000000) > (b+0x80000000)) { // a > b as unsigned
1966+
if (((a + 0x80000000)|0) > ((b + 0x80000000)|0)) { // a > b as unsigned
19671967
a -= b;
19681968
a >>>= Integer.numberOfTrailingZeros(a);
19691969
} else {
@@ -2246,4 +2246,20 @@ MutableBigInteger euclidModInverse(int k) {
22462246
mod.subtract(t1);
22472247
return mod;
22482248
}
2249+
2250+
// static {
2251+
// int a = 100;
2252+
// int b = a + 0x80000000;
2253+
// System.out.println(b);
2254+
// System.out.println((a + 0x80000000) | 0);
2255+
// System.out.println(a + 0x80000000L); // NOT in Java
2256+
// System.out.println((int) (a + 0x80000000L));
2257+
// a = -100;
2258+
// b = a + 0x80000000;
2259+
// System.out.println("?");
2260+
// System.out.println(b); //NOT in JS
2261+
// System.out.println((a + 0x80000000) | 0);
2262+
// System.out.println(a + 0x80000000L);
2263+
// System.out.println((int) (a + 0x80000000L));
2264+
// }
22492265
}

sources/net.sf.j2s.java.core/src/test/math/MutableBigInteger.java

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ private int compareShifted(MutableBigInteger b, int ints) {
294294
// comparison.
295295
int[] bval = b.value;
296296
for (int i = offset, j = b.offset; i < alen + offset; i++, j++) {
297-
int b1 = value[i] + 0x80000000;
298-
int b2 = bval[j] + 0x80000000;
297+
int b1 = (value[i] + 0x80000000)|0;
298+
int b2 = (bval[j] + 0x80000000)|0;
299299
if (b1 < b2)
300300
return -1;
301301
if (b1 > b2)
@@ -889,9 +889,11 @@ void addDisjoint(MutableBigInteger addend, int n) {
889889
for (int i=rstart+1-y+len; i < rstart+1; i++)
890890
result[i] = 0;
891891

892-
value = result;
893892
intLen = resultLen;
894893
offset = result.length - resultLen;
894+
895+
value = result;
896+
895897
}
896898

897899
/**
@@ -939,18 +941,17 @@ int subtract(MutableBigInteger b) {
939941
// Subtract common parts of both numbers
940942
while (y > 0) {
941943
x--; y--;
942-
943-
diff = (a.value[x+a.offset] & LONG_MASK) -
944-
(b.value[y+b.offset] & LONG_MASK) - ((int)-(diff>>32));
944+
// 2024.02.22 BH long-long-int fails, now (long-long)-int
945+
diff = ((a.value[x+a.offset] & LONG_MASK)
946+
- (b.value[y+b.offset] & LONG_MASK)) - (int)-(diff>>32);
945947
result[rstart--] = (int)diff;
946948
}
947-
// Subtract remainder of longer number
949+
// Subtract remainder of longer number
948950
while (x > 0) {
949951
x--;
950-
diff = (a.value[x+a.offset] & LONG_MASK) - ((int)-(diff>>32));
952+
diff = (a.value[x+a.offset] & LONG_MASK) - (int)-(diff>>32);
951953
result[rstart--] = (int)diff;
952954
}
953-
954955
value = result;
955956
intLen = resultLen;
956957
offset = value.length - resultLen;
@@ -1261,6 +1262,8 @@ MutableBigInteger divideAndRemainderBurnikelZiegler(MutableBigInteger b, Mutable
12611262
int n = j * m; // step 2b: block length in 32-bit units
12621263
long n32 = 32L * n; // block length in bits
12631264
int sigma = (int) Math.max(0, n32 - b.bitLength()); // step 3: sigma = max{T | (2^T)*B < beta^n}
1265+
1266+
12641267
MutableBigInteger bShifted = new MutableBigInteger(b);
12651268
bShifted.safeLeftShift(sigma); // step 4a: shift b so its length is a multiple of n
12661269
MutableBigInteger aShifted = new MutableBigInteger (this);
@@ -1278,7 +1281,6 @@ MutableBigInteger divideAndRemainderBurnikelZiegler(MutableBigInteger b, Mutable
12781281
// step 7: z[t-2] = [a[t-1], a[t-2]]
12791282
MutableBigInteger z = aShifted.getBlock(t-2, t, n); // the second to most significant block
12801283
z.addDisjoint(a1, n); // z[t-2]
1281-
12821284
// do schoolbook division on blocks, dividing 2-block numbers by 1-block numbers
12831285
MutableBigInteger qi = new MutableBigInteger();
12841286
MutableBigInteger ri;
@@ -1356,7 +1358,6 @@ private MutableBigInteger divide3n2n(MutableBigInteger b, MutableBigInteger quot
13561358
MutableBigInteger b1 = new MutableBigInteger(b);
13571359
b1.safeRightShift(n * 32);
13581360
BigInteger b2 = b.getLower(n);
1359-
13601361
MutableBigInteger r;
13611362
MutableBigInteger d;
13621363
if (compareShifted(b, n) < 0) {
@@ -1381,6 +1382,7 @@ private MutableBigInteger divide3n2n(MutableBigInteger b, MutableBigInteger quot
13811382

13821383
// step 5: r = r*beta^n + a3 - d (paper says a4)
13831384
// However, don't subtract d until after the while loop so r doesn't become negative
1385+
13841386
r.leftShift(32 * n);
13851387
r.addLower(this, n);
13861388

@@ -1390,7 +1392,6 @@ private MutableBigInteger divide3n2n(MutableBigInteger b, MutableBigInteger quot
13901392
quotient.subtract(MutableBigInteger.ONE);
13911393
}
13921394
r.subtract(d);
1393-
13941395
return r;
13951396
}
13961397

@@ -1548,13 +1549,13 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
15481549
int qrem = 0;
15491550
boolean skipCorrection = false;
15501551
int nh = rem.value[j+rem.offset];
1551-
int nh2 = nh + 0x80000000;
1552+
int nh2 = (nh + 0x80000000)|0;
15521553
int nm = rem.value[j+1+rem.offset];
15531554

15541555
if (nh == dh) {
15551556
qhat = ~0;
15561557
qrem = nh + nm;
1557-
skipCorrection = qrem + 0x80000000 < nh2;
1558+
skipCorrection = ((qrem + 0x80000000)|0) < nh2;
15581559
} else {
15591560
long nChunk = (((long)nh) << 32) | (nm & LONG_MASK);
15601561
if (nChunk >= 0) {
@@ -1592,7 +1593,7 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
15921593
int borrow = mulsub(rem.value, divisor, qhat, dlen, j+rem.offset);
15931594

15941595
// D5 Test remainder
1595-
if (borrow + 0x80000000 > nh2) {
1596+
if (((borrow + 0x80000000)|0) > nh2) {
15961597
// D6 Add back
15971598
divadd(divisor, rem.value, j+1+rem.offset);
15981599
qhat--;
@@ -1607,13 +1608,13 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
16071608
int qrem = 0;
16081609
boolean skipCorrection = false;
16091610
int nh = rem.value[limit - 1 + rem.offset];
1610-
int nh2 = nh + 0x80000000;
1611+
int nh2 = (nh + 0x80000000)|0;
16111612
int nm = rem.value[limit + rem.offset];
16121613

16131614
if (nh == dh) {
16141615
qhat = ~0;
16151616
qrem = nh + nm;
1616-
skipCorrection = qrem + 0x80000000 < nh2;
1617+
skipCorrection = ((qrem + 0x80000000)|0) < nh2;
16171618
} else {
16181619
long nChunk = (((long) nh) << 32) | (nm & LONG_MASK);
16191620
if (nChunk >= 0) {
@@ -1653,7 +1654,7 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
16531654
borrow = mulsubBorrow(rem.value, divisor, qhat, dlen, limit - 1 + rem.offset);
16541655

16551656
// D5 Test remainder
1656-
if (borrow + 0x80000000 > nh2) {
1657+
if (((borrow + 0x80000000)|0) > nh2) {
16571658
// D6 Add back
16581659
if(needRemainder)
16591660
divadd(divisor, rem.value, limit - 1 + 1 + rem.offset);
@@ -1723,13 +1724,13 @@ private MutableBigInteger divideLongMagnitude(long ldivisor, MutableBigInteger q
17231724
int qrem = 0;
17241725
boolean skipCorrection = false;
17251726
int nh = rem.value[j + rem.offset];
1726-
int nh2 = nh + 0x80000000;
1727+
int nh2 = (nh + 0x80000000)|0;
17271728
int nm = rem.value[j + 1 + rem.offset];
17281729

17291730
if (nh == dh) {
17301731
qhat = ~0;
17311732
qrem = nh + nm;
1732-
skipCorrection = qrem + 0x80000000 < nh2;
1733+
skipCorrection = ((qrem + 0x80000000)|0) < nh2;
17331734
} else {
17341735
long nChunk = (((long) nh) << 32) | (nm & LONG_MASK);
17351736
if (nChunk >= 0) {
@@ -1767,7 +1768,7 @@ private MutableBigInteger divideLongMagnitude(long ldivisor, MutableBigInteger q
17671768
int borrow = mulsubLong(rem.value, dh, dl, qhat, j + rem.offset);
17681769

17691770
// D5 Test remainder
1770-
if (borrow + 0x80000000 > nh2) {
1771+
if (((borrow + 0x80000000)|0) > nh2) {
17711772
// D6 Add back
17721773
divaddLong(dh,dl, rem.value, j + 1 + rem.offset);
17731774
qhat--;
@@ -1963,7 +1964,7 @@ static int binaryGcd(int a, int b) {
19631964
int t = (aZeros < bZeros ? aZeros : bZeros);
19641965

19651966
while (a != b) {
1966-
if ((a+0x80000000) > (b+0x80000000)) { // a > b as unsigned
1967+
if (((a+0x80000000)|0) > ((b+0x80000000)|0)) { // a > b as unsigned
19671968
a -= b;
19681969
a >>>= Integer.numberOfTrailingZeros(a);
19691970
} else {

0 commit comments

Comments
 (0)