3535
3636/**
3737 *
38- * SwingJS note: This is only a minimal implementation.
38+ * SwingJS note: Because of the limitations of JavaScript with regard
39+ * to long-integer bit storage as a double, this implementation drops
40+ * the integer storage bit length to 26, giving 52 for long and leaving
41+ * the last 12 bits for the exponent of the double number. This should
42+ * not affect performance significantly. It does increase the storage
43+ * size by about 25%.
3944 *
4045 * Immutable arbitrary-precision integers. All operations behave as if
4146 * BigIntegers were represented in two's-complement notation (like Java's
@@ -226,33 +231,38 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
226231 @ Deprecated
227232 private int firstNonzeroIntNum ;
228233
234+ private long THIRD_CARRY = 0x155556L ;//for 26-bit; 32-bit is 0x55555556L;
235+ private long THIRD_MULT = 0x2AAAAABL ;//for 26-bit; 32-bit is 0xAAAAAAABL
229236 private static Random myRandom ;
230237
231238 /**
232239 * This mask is used to obtain the value of an int as if it were unsigned.
233240 *
234241 * SwingJS : ANDing and ORing in JavaScript result in 32-bit numbers
235242 */
236- static long LONG_MASK = /** @j2sNative Math.pow(2,32) - 1 ||*/ 0xffffffffL ;
243+
244+ static int N_BITS = 26 ;
245+ static int SPARE_BITS = 32 - N_BITS ;
246+ static long LONG_MASK = (1 << N_BITS ) - 1 ;// 0xffffffffL;
237247
238- static long TWO_TO_32 = LONG_MASK + 1 ;
248+ static long FIRST_HIGH = LONG_MASK + 1 ;
239249
240250
241- static final double [] TWO_TO_THE = new double [55 ];
251+ static final double [] TWO_TO_THE = new double [52 ];
242252 // can't use << in JavaScript for large numbers
243253 static {
244254 TWO_TO_THE [0 ] = 1 ;
245- for (int i = 1 ; i <= 54 ; i ++)
255+ for (int i = 1 ; i <= N_BITS * 2 ; i ++)
246256 TWO_TO_THE [i ] = TWO_TO_THE [i - 1 ] * 2 ;
247257 }
248258
249259 static int longNumberOfLeadingZeros (long x ) {
250- int n = 0 ;
260+ int n = - SPARE_BITS ;
251261 long y = getHighBits (x );
252262 if (y == 0 ) {
253263 x = getLowBits (x );
254264 } else {
255- n = 32 ;
265+ n = N_BITS - 2 * SPARE_BITS ;
256266 x = y ;
257267 }
258268 return n + Integer .numberOfLeadingZeros ((int ) x );
@@ -261,11 +271,11 @@ static int longNumberOfLeadingZeros(long x) {
261271 static long getLowBits (long y ) {
262272 // was y & LONG_MASK;
263273 y = ((int ) y ) | 0 ;
264- return (y < 0 ? TWO_TO_32 + y : y );
274+ return (y < 0 ? FIRST_HIGH + y : y );
265275 }
266276
267277 static long toHighBits (long x ) {
268- return longLeftShift (getLowBits (x ), 32 );
278+ return longLeftShift (getLowBits (x ), N_BITS );
269279 }
270280
271281 static long longLeftShift (long x , int n ) {
@@ -277,7 +287,7 @@ static long toLongBits(long highbits, long lowbits) {
277287 }
278288
279289 static long getHighBits (long x ) {
280- return longRightShift (x , 32 );
290+ return longRightShift (x , N_BITS );
281291 }
282292
283293 static long longRightShift (long x , int n ) {
@@ -286,7 +296,7 @@ static long longRightShift(long x, int n) {
286296 long tttn = doubleToLong (TWO_TO_THE [n ]);
287297 x = (x - getLowBits ((x & (tttn - 1 )))) / tttn ;
288298 // clear high bits if necessary
289- return (x < 0 && n > 32 ? x & (doubleToLong (TWO_TO_THE [64 - n ]) - 1 ) : x );
299+ return x ; // (x < 0 && n > 32 ? x & (doubleToLong(TWO_TO_THE[ - n]) - 1) : x);
290300 }
291301
292302 private static long doubleToLong (double d ) {
@@ -645,7 +655,7 @@ public BigInteger(String val, int radix) {
645655 // Pre-allocate array of expected size. May be too large but can
646656 // never be too small. Typically exact.
647657 long numBits = ((numDigits * bitsPerDigit [radix ]) >>> 10 ) + 1 ;
648- if (numBits + 31 >= TWO_TO_32 ) {
658+ if (numBits + 31 >= FIRST_HIGH ) {
649659 reportOverflow ();
650660 }
651661 int numWords = (int ) (numBits + 31 ) >>> 5 ;
@@ -703,7 +713,7 @@ public BigInteger(String val, int radix) {
703713 numWords = 1 ;
704714 } else {
705715 long numBits = ((numDigits * bitsPerDigit [10 ]) >>> 10 ) + 1 ;
706- if (numBits + 31 >= TWO_TO_32 ) {
716+ if (numBits + 31 >= FIRST_HIGH ) {
707717 reportOverflow ();
708718 }
709719 numWords = (int ) (numBits + 31 ) >>> 5 ;
@@ -1479,7 +1489,7 @@ private static int[] subtract(long val, int[] little) {
14791489 long difference = getLowBits (val ) - getLowBits (little [0 ]);
14801490 result [1 ] = (int )difference ;
14811491 // Subtract remainder of longer number while borrow propagates
1482- boolean borrow = (difference >> 32 != 0 );
1492+ boolean borrow = (getHighBits ( difference ) != 0 );
14831493 if (borrow ) {
14841494 result [0 ] = highWord - 1 ;
14851495 } else { // Copy remainder of longer number
@@ -1488,9 +1498,9 @@ private static int[] subtract(long val, int[] little) {
14881498 return result ;
14891499 } else { // little.length == 2
14901500 long difference = getLowBits (val ) - getLowBits (little [1 ]);
1491- result [1 ] = (int )difference ;
1492- difference = getLowBits (highWord ) - getLowBits (little [0 ]) + (difference >> 32 );
1493- result [0 ] = (int )difference ;
1501+ result [1 ] = (int ) difference ;
1502+ difference = getLowBits (highWord ) - getLowBits (little [0 ]) + getHighBits (difference );
1503+ result [0 ] = (int ) difference ;
14941504 return result ;
14951505 }
14961506 }
@@ -1515,12 +1525,12 @@ private static int[] subtract(int[] big, long val) {
15151525 } else {
15161526 difference = getLowBits (big [--bigIndex ]) - getLowBits (val );
15171527 result [bigIndex ] = (int )difference ;
1518- difference = getLowBits (big [--bigIndex ]) - getLowBits (highWord ) + (difference >> 32 );
1528+ difference = getLowBits (big [--bigIndex ]) - getLowBits (highWord ) + getHighBits (difference );
15191529 result [bigIndex ] = (int )difference ;
15201530 }
15211531
15221532 // Subtract remainder of longer number while borrow propagates
1523- boolean borrow = (difference >> 32 != 0 );
1533+ boolean borrow = (getHighBits ( difference ) != 0 );
15241534 while (bigIndex > 0 && borrow )
15251535 borrow = ((result [--bigIndex ] = big [bigIndex ] - 1 ) == -1 );
15261536
@@ -1570,12 +1580,12 @@ private static int[] subtract(int[] big, int[] little) {
15701580 while (littleIndex > 0 ) {
15711581 difference = getLowBits (big [--bigIndex ]) -
15721582 getLowBits (little [--littleIndex ]) +
1573- (difference >> 32 );
1583+ getHighBits (difference );
15741584 result [bigIndex ] = (int )difference ;
15751585 }
15761586
15771587 // Subtract remainder of longer number while borrow propagates
1578- boolean borrow = (difference >> 32 != 0 );
1588+ boolean borrow = (getHighBits ( difference ) != 0 );
15791589 while (bigIndex > 0 && borrow )
15801590 borrow = ((result [--bigIndex ] = big [bigIndex ] - 1 ) == -1 );
15811591
@@ -1762,7 +1772,10 @@ private static BigInteger multiplyKaratsuba(BigInteger x, BigInteger y) {
17621772 BigInteger p3 = xh .add (xl ).multiply (yh .add (yl ));
17631773
17641774 // result = p1 * 2^(32*2*half) + (p3 - p1 - p2) * 2^(32*half) + p2
1765- BigInteger result = p1 .shiftLeft (32 *half ).add (p3 .subtract (p1 ).subtract (p2 )).shiftLeft (32 *half ).add (p2 );
1775+ BigInteger result = p1 .shiftLeft (N_BITS *half )
1776+ .add (p3 .subtract (p1 ).subtract (p2 ))
1777+ .shiftLeft (N_BITS *half )
1778+ .add (p2 );
17661779
17671780 if (x .signum != y .signum ) {
17681781 return result .negate ();
@@ -1849,9 +1862,12 @@ private static BigInteger multiplyToomCook3(BigInteger a, BigInteger b) {
18491862 tm1 = tm1 .subtract (t2 );
18501863
18511864 // Number of bits to shift left.
1852- int ss = k *32 ;
1865+ int ss = k *N_BITS ;
18531866
1854- BigInteger result = vinf .shiftLeft (ss ).add (t2 ).shiftLeft (ss ).add (t1 ).shiftLeft (ss ).add (tm1 ).shiftLeft (ss ).add (v0 );
1867+ BigInteger result = vinf .shiftLeft (ss ).add (t2 )
1868+ .shiftLeft (ss ).add (t1 )
1869+ .shiftLeft (ss ).add (tm1 )
1870+ .shiftLeft (ss ).add (v0 );
18551871
18561872 if (a .signum != b .signum ) {
18571873 return result .negate ();
@@ -1939,14 +1955,15 @@ private BigInteger exactDivideBy3() {
19391955 // 0xAAAAAAAB is the modular inverse of 3 (mod 2^32). Thus,
19401956 // the effect of this is to divide by 3 (mod 2^32).
19411957 // This is much faster than division on most architectures.
1942- q = getLowBits ((w * 0xAAAAAAABL ));
1958+ q = getLowBits ((w * THIRD_MULT ));
19431959 result [i ] = (int ) q ;
19441960
1961+ // SWINGJS TODO - CHECK THIS
19451962 // Now check the borrow. The second check can of course be
19461963 // eliminated if the first fails.
1947- if (q >= 0x55555556L ) {
1964+ if (q >= THIRD_CARRY ) {
19481965 borrow ++;
1949- if (q >= 0xAAAAAAABL )
1966+ if (q >= THIRD_MULT )
19501967 borrow ++;
19511968 }
19521969 }
@@ -2099,7 +2116,9 @@ private BigInteger squareKaratsuba() {
20992116 BigInteger xls = xl .square (); // xls = xl^2
21002117
21012118 // xh^2 << 64 + (((xl+xh)^2 - (xh^2 + xl^2)) << 32) + xl^2
2102- return xhs .shiftLeft (half *32 ).add (xl .add (xh ).square ().subtract (xhs .add (xls ))).shiftLeft (half *32 ).add (xls );
2119+ return xhs .shiftLeft (half *N_BITS ).add (xl .add (xh )
2120+ .square ().subtract (xhs .add (xls )))
2121+ .shiftLeft (half *N_BITS ).add (xls );
21032122 }
21042123
21052124 /**
@@ -2149,9 +2168,12 @@ private BigInteger squareToomCook3() {
21492168 tm1 = tm1 .subtract (t2 );
21502169
21512170 // Number of bits to shift left.
2152- int ss = k *32 ;
2171+ int ss = k *N_BITS ;
21532172
2154- return vinf .shiftLeft (ss ).add (t2 ).shiftLeft (ss ).add (t1 ).shiftLeft (ss ).add (tm1 ).shiftLeft (ss ).add (v0 );
2173+ return vinf .shiftLeft (ss ).add (t2 )
2174+ .shiftLeft (ss ).add (t1 )
2175+ .shiftLeft (ss ).add (tm1 )
2176+ .shiftLeft (ss ).add (v0 );
21552177 }
21562178
21572179 // Division
@@ -2903,11 +2925,11 @@ private static int subN(int[] a, int[] b, int len) {
29032925
29042926 while (--len >= 0 ) {
29052927 sum = getLowBits (a [len ]) -
2906- getLowBits (b [len ]) + (sum >> 32 );
2928+ getLowBits (b [len ]) + getHighBits (sum );
29072929 a [len ] = (int )sum ;
29082930 }
29092931
2910- return (int )(sum >> 32 );
2932+ return (int )getHighBits (sum );
29112933 }
29122934
29132935 /**
0 commit comments