Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita826557

Browse files
committed
fixes MutableBigInteger (mostly for BigDecimal) not set to roll over
integer on overflow. issue #270 and related
1 parent8d78ad0 commita826557

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
packagejava.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 (inti =offset,j =b.offset;i <alen +offset;i++,j++) {
297-
intb1 =value[i] +0x80000000;
298-
intb2 =bval[j] +0x80000000;
299+
intb1 =(value[i] +0x80000000)|0;
300+
intb2 =(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
longv =val[i++] &LONG_MASK;
340342
if (v !=hb)
341343
returnv <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
returncarry ==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 =newMutableBigInteger(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(newMutableBigInteger(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
intqrem =0;
15491549
booleanskipCorrection =false;
15501550
intnh =rem.value[j+rem.offset];
1551-
intnh2 =nh +0x80000000;
1551+
intnh2 =(nh +0x80000000)|0;
15521552
intnm =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
longnChunk = (((long)nh) <<32) | (nm &LONG_MASK);
15601560
if (nChunk >=0) {
@@ -1607,13 +1607,13 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
16071607
intqrem =0;
16081608
booleanskipCorrection =false;
16091609
intnh =rem.value[limit -1 +rem.offset];
1610-
intnh2 =nh +0x80000000;
1610+
intnh2 =(nh +0x80000000)|0;
16111611
intnm =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
longnChunk = (((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
intqrem =0;
17241724
booleanskipCorrection =false;
17251725
intnh =rem.value[j +rem.offset];
1726-
intnh2 =nh +0x80000000;
1726+
intnh2 =(nh +0x80000000)|0;
17271727
intnm =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
longnChunk = (((long)nh) <<32) | (nm &LONG_MASK);
17351735
if (nChunk >=0) {
@@ -1767,7 +1767,7 @@ private MutableBigInteger divideLongMagnitude(long ldivisor, MutableBigInteger q
17671767
intborrow =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
intt = (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
returnmod;
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 (inti =offset,j =b.offset;i <alen +offset;i++,j++) {
297-
intb1 =value[i] +0x80000000;
298-
intb2 =bval[j] +0x80000000;
297+
intb1 =(value[i] +0x80000000)|0;
298+
intb2 =(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 (inti=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
intn =j *m;// step 2b: block length in 32-bit units
12621263
longn32 =32L *n;// block length in bits
12631264
intsigma = (int)Math.max(0,n32 -b.bitLength());// step 3: sigma = max{T | (2^T)*B < beta^n}
1265+
1266+
12641267
MutableBigIntegerbShifted =newMutableBigInteger(b);
12651268
bShifted.safeLeftShift(sigma);// step 4a: shift b so its length is a multiple of n
12661269
MutableBigIntegeraShifted =newMutableBigInteger (this);
@@ -1278,7 +1281,6 @@ MutableBigInteger divideAndRemainderBurnikelZiegler(MutableBigInteger b, Mutable
12781281
// step 7: z[t-2] = [a[t-1], a[t-2]]
12791282
MutableBigIntegerz =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
MutableBigIntegerqi =newMutableBigInteger();
12841286
MutableBigIntegerri;
@@ -1356,7 +1358,6 @@ private MutableBigInteger divide3n2n(MutableBigInteger b, MutableBigInteger quot
13561358
MutableBigIntegerb1 =newMutableBigInteger(b);
13571359
b1.safeRightShift(n *32);
13581360
BigIntegerb2 =b.getLower(n);
1359-
13601361
MutableBigIntegerr;
13611362
MutableBigIntegerd;
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
returnr;
13951396
}
13961397

@@ -1548,13 +1549,13 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
15481549
intqrem =0;
15491550
booleanskipCorrection =false;
15501551
intnh =rem.value[j+rem.offset];
1551-
intnh2 =nh +0x80000000;
1552+
intnh2 =(nh +0x80000000)|0;
15521553
intnm =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
longnChunk = (((long)nh) <<32) | (nm &LONG_MASK);
15601561
if (nChunk >=0) {
@@ -1592,7 +1593,7 @@ private MutableBigInteger divideMagnitude(MutableBigInteger div,
15921593
intborrow =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
intqrem =0;
16081609
booleanskipCorrection =false;
16091610
intnh =rem.value[limit -1 +rem.offset];
1610-
intnh2 =nh +0x80000000;
1611+
intnh2 =(nh +0x80000000)|0;
16111612
intnm =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
longnChunk = (((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
intqrem =0;
17241725
booleanskipCorrection =false;
17251726
intnh =rem.value[j +rem.offset];
1726-
intnh2 =nh +0x80000000;
1727+
intnh2 =(nh +0x80000000)|0;
17271728
intnm =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
longnChunk = (((long)nh) <<32) | (nm &LONG_MASK);
17351736
if (nChunk >=0) {
@@ -1767,7 +1768,7 @@ private MutableBigInteger divideLongMagnitude(long ldivisor, MutableBigInteger q
17671768
intborrow =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
intt = (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)

[8]ページ先頭

©2009-2025 Movatter.jp