This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Re: BigInteger patch (long)
- From: "Raif S. Naffah" <raif at fl dot net dot au>
- To: tromey at redhat dot com
- Cc: java-patches at gcc dot gnu dot org
- Date: Sat, 1 Feb 2003 13:36:30 +1100
- Subject: Re: BigInteger patch (long)
- References: <200212262244.25772.raif@fl.net.au> <87znphvt1z.fsf@fleche.redhat.com>
- Reply-to: raif at fl dot net dot au
On Saturday 01 February 2003 09:43, Tom Tromey wrote:
> >>>>> "Raif" == Raif S Naffah <raif@fl.net.au> writes:
>
> Raif> the following is the diff for a modified BigInteger:
> Raif> [ ...]
>
> Sorry for the delay on this.
>
> Per ok'd this, so I was going to check it in today.
> Could you write a ChangeLog entry first though?
> This patch is pretty big and I'm not sure I could do it justice.
> Also if you could remove the commented-out code and resend the patch,
> that would help too.
here they are:
cvs -z9 diff -u -wb -B ChangeLog (in directory /data/workspace/cvs/gcc/)
Index: ChangeLog
===================================================================
RCS file: /cvsroot/gcc/gcc/ChangeLog,v
retrieving revision 1.669
diff -u -w -b -B -r1.669 ChangeLog
--- ChangeLog 30 Jan 2003 22:44:14 -0000 1.669
+++ ChangeLog 1 Feb 2003 02:27:29 -0000
@@ -1,3 +1,68 @@
+2003-02-01 Raif S. Naffah <raif@fl.net.au>
+
+ * libjava/java/math/BigInteger.java:
+ copyright: Updated notice to include years 2002 and 3.
+ fields: Added 2 private (int) arrays with values from the HAC
+ (Handbook of Applied Cryptography -A. Menezes & al): k[] that
+ contains bit lengths and t[] that contains nbr. of tests --used in
+ isProbablePrime().
+ make(long) and valueOf(long): Merged into valueOf(long).
+ make(int[],int): Use valueOf(long) instead of make(long).
+ byteArrayToIntArray(): Removed casting to (int). this is std. behaviour.
+ alloc(int): Always instantiate a new BI.
+ isOdd(): Removed. not used.
+ isMinusOne(): Removed. not used.
+ canonicalize(): Removed casting to (int).
+ add(int,int): Use valueOf(long) instead of make(long).
+ add(BI,BI,int): Use valueOf(long) instead of make(long).
+ times(BI,int): Use valueOf(long) instead of make(long).
+ divide(long,long,BI,BI,int): Use valueOf(long) instead of make(long).
+ pow(BI): Removed. not used.
+ pow(int): Removed 'else' keyword.
+ euclidInv(int,int,int): Now returns an array of 2 ints instead of 3.
+ the 3rd param was a work var. Amended code uses the local copy of
+ the 1st param for the same purpose.
+ euclidInv(BI,BI,BI): Used to return an array of 2 BIs; now accepts 6
+ BIs and returns void. The new 3 additional params are used as work
+ vars and should be instantiated and passed at the discretion of the
+ caller --reduces overall number of objects when recursion occurs.
+ modInverse(BI): Use new signatures of euclidInv().
+ modPow(BI,BI): Fixed spelling.
+ Combined declaration with initialisation of locals.
+ Removed unused var.
+ gcd(int,int): Declared 'tmp' once as local var and used everywhere where
+ needed.
+ gcd(BI): Use valueOf(long) instead of make(long).
+ Use static methods name in same class w/o prepending class name.
+ isProbablePrime(int): Use divide() with static small primes, and test
+ remainder value directly as opposed to invoking remainder().
+ Use valueOf(long) instead of make(long).
+ Use pre-computed max nbr of trials based on bitlength of BI to test.
+ values (in static k[] and t[] arrays described earlier) are from the
+ HAC and are for a probability of 1/2**80. if caller wants better than
+ 1/2**80 the current implementation now doubles this pre-computed limit.
+ Now use pre-computed small primes for the trial tests instead of random
+ numbers --a strategy recommended by the HAC.
+ shift(BI,int): Use valueOf(long) instead of make(long).
+ format(int,StringBuffer): Removed invoacation of MPN.chars_per_word().
+ not used.
+ toString(int): Removed 'else' keyword.
+ equals(Object): Use static methods name in same class w/o prepending
+ class name.
+ valueOf(String,int): Use valueOf(long) instead of make(long).
+ doubleValue(): Removed 'else' keyword.
+ Use static methods name in same class w/o prepending class name.
+ setNegative(BI): Use static methods name in same class w/o prepending
+ class name.
+ neg(BI): Use valueOf(long) instead of make(long).
+ negate(): Use static methods name in same class w/o prepending class
+ name.
+ bitLength(): Removed 'else' keyword.
+ bitOp(int,BI,BI): Use valueOf(long) instead of make(long).
+ and(BI,int): Use valueOf(long) instead of make(long).
+ Use static methods name in same class w/o prepending class name.
+ and(BI): Use methods name in same class w/o prepending class name.
+
2003-01-30 Roger Sayle <roger@eyesopen.com>
* config.guess: Updated to 2003-01-30's version.
cvs -z9 diff -u -wb -B BigInteger.java (in directory /data/workspace/cvs/gcc/libjava/java/math/)
Index: BigInteger.java
===================================================================
RCS file: /cvsroot/gcc/gcc/libjava/java/math/BigInteger.java,v
retrieving revision 1.19
diff -u -w -b -B -r1.19 BigInteger.java
--- BigInteger.java 19 Dec 2002 06:59:46 -0000 1.19
+++ BigInteger.java 1 Feb 2003 02:29:22 -0000
@@ -1,5 +1,5 @@
/* java.math.BigInteger -- Arbitary precision integers
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -110,6 +108,12 @@
109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181,
191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251 };
+ /** HAC (Handbook of Applied Cryptography), Alfred Menezes & al. Table 4.4. */
+ private static final int[] k =
+ {100,150,200,250,300,350,400,500,600,800,1250, Integer.MAX_VALUE};
+ private static final int[] t =
+ { 27, 18, 15, 12, 9, 8, 7, 6, 5, 4, 3, 2};
+
private BigInteger()
{
}
@@ -218,38 +222,29 @@
}
/** Return a (possibly-shared) BigInteger with a given long value. */
- private static BigInteger make(long value)
+ public static BigInteger valueOf(long val)
{
- if (value >= minFixNum && value <= maxFixNum)
- return smallFixNums[(int)value - minFixNum];
- int i = (int) value;
- if ((long)i == value)
+ if (val >= minFixNum && val <= maxFixNum)
+ return smallFixNums[(int) val - minFixNum];
+ int i = (int) val;
+ if ((long) i == val)
return new BigInteger(i);
BigInteger result = alloc(2);
result.ival = 2;
result.words[0] = i;
- result.words[1] = (int) (value >> 32);
+ result.words[1] = (int)(val >> 32);
return result;
}
- // FIXME: Could simply rename 'make' method above as valueOf while
- // changing all instances of 'make'. Don't do this until this class
- // is done as the Kawa class this is based on has 'make' methods
- // with other parameters; wait to see if they are used in BigInteger.
- public static BigInteger valueOf(long val)
- {
- return make(val);
- }
-
/** Make a canonicalized BigInteger from an array of words.
* The array may be reused (without copying). */
private static BigInteger make(int[] words, int len)
{
if (words == null)
- return make(len);
+ return valueOf(len);
len = BigInteger.wordsNeeded(words, len);
if (len <= 1)
- return len == 0 ? ZERO : make(words[0]);
+ return len == 0 ? ZERO : valueOf(words[0]);
BigInteger num = new BigInteger();
num.words = words;
num.ival = len;
@@ -267,15 +262,15 @@
int bptr = 0;
int word = sign;
for (int i = bytes.length % 4; i > 0; --i, bptr++)
- word = (word << 8) | (((int) bytes[bptr]) & 0xff);
+ word = (word << 8) | (bytes[bptr] & 0xff);
words[--nwords] = word;
// Elements remaining in byte[] are a multiple of 4.
while (nwords > 0)
words[--nwords] = bytes[bptr++] << 24 |
- (((int) bytes[bptr++]) & 0xff) << 16 |
- (((int) bytes[bptr++]) & 0xff) << 8 |
- (((int) bytes[bptr++]) & 0xff);
+ (bytes[bptr++] & 0xff) << 16 |
+ (bytes[bptr++] & 0xff) << 8 |
+ (bytes[bptr++] & 0xff);
return words;
}
@@ -284,9 +279,8 @@
*/
private static BigInteger alloc(int nwords)
{
- if (nwords <= 1)
- return new BigInteger();
BigInteger result = new BigInteger();
+ if (nwords > 1)
result.words = new int[nwords];
return result;
}
@@ -376,12 +370,6 @@
return compareTo(this, val) > 0 ? this : val;
}
- private final boolean isOdd()
- {
- int low = words == null ? ival : words[0];
- return (low & 1) != 0;
- }
-
private final boolean isZero()
{
return words == null && ival == 0;
@@ -392,11 +380,6 @@
return words == null && ival == 1;
}
- private final boolean isMinusOne()
- {
- return words == null && ival == -1;
- }
-
/** Calculate how many words are significant in words[0:len-1].
* Returns the least value x such that x>0 && words[0:x-1]==words[0:len-1],
* when words is viewed as a 2's complement integer.
@@ -433,14 +416,14 @@
words = null;
}
if (words == null && ival >= minFixNum && ival <= maxFixNum)
- return smallFixNums[(int) ival - minFixNum];
+ return smallFixNums[ival - minFixNum];
return this;
}
/** Add two ints, yielding a BigInteger. */
private static final BigInteger add(int x, int y)
{
- return BigInteger.make((long) x + (long) y);
+ return valueOf((long) x + (long) y);
}
/** Add a BigInteger and an int, yielding a new BigInteger. */
@@ -526,13 +509,13 @@
private static BigInteger add(BigInteger x, BigInteger y, int k)
{
if (x.words == null && y.words == null)
- return BigInteger.make((long) k * (long) y.ival + (long) x.ival);
+ return valueOf((long) k * (long) y.ival + (long) x.ival);
if (k != 1)
{
if (k == -1)
y = BigInteger.neg(y);
else
- y = BigInteger.times(y, BigInteger.make(k));
+ y = BigInteger.times(y, valueOf(k));
}
if (x.words == null)
return BigInteger.add(y, x.ival);
@@ -580,7 +563,7 @@
int[] xwords = x.words;
int xlen = x.ival;
if (xwords == null)
- return BigInteger.make((long) xlen * (long) y);
+ return valueOf((long) xlen * (long) y);
boolean negative;
BigInteger result = BigInteger.alloc(xlen + 1);
if (xwords[xlen - 1] < 0)
@@ -662,7 +645,7 @@
xNegative = true;
if (x == Long.MIN_VALUE)
{
- divide(BigInteger.make(x), BigInteger.make(y),
+ divide(valueOf(x), valueOf(y),
quotient, remainder, rounding_mode);
return;
}
@@ -684,7 +667,7 @@
remainder.set(x);
}
else
- divide(BigInteger.make(x), BigInteger.make(y),
+ divide(valueOf(x), valueOf(y),
quotient, remainder, rounding_mode);
return;
}
@@ -966,39 +949,6 @@
return rem.canonicalize();
}
- /** Calculate power for BigInteger exponents.
- * @param y exponent assumed to be non-negative. */
- private BigInteger pow(BigInteger y)
- {
- if (isOne())
- return this;
- if (isMinusOne())
- return y.isOdd () ? this : ONE;
- if (y.words == null && y.ival >= 0)
- return pow(y.ival);
-
- // Assume exponent is non-negative.
- if (isZero())
- return this;
-
- // Implemented by repeated squaring and multiplication.
- BigInteger pow2 = this;
- BigInteger r = null;
- for (;;) // for (i = 0; ; i++)
- {
- // pow2 == x**(2**i)
- // prod = x**(sum(j=0..i-1, (y>>j)&1))
- if (y.isOdd())
- r = r == null ? pow2 : times(r, pow2); // r *= pow2
- y = BigInteger.shift(y, -1);
- if (y.isZero())
- break;
- // pow2 *= pow2;
- pow2 = times(pow2, pow2);
- }
- return r == null ? ONE : r;
- }
-
/** Calculate the integral power of a BigInteger.
* @param exponent the exponent (must be non-negative)
*/
@@ -1008,7 +958,6 @@
{
if (exponent == 0)
return ONE;
- else
throw new ArithmeticException("negative exponent");
}
if (isZero())
@@ -1051,51 +1000,36 @@
private static final int[] euclidInv(int a, int b, int prevDiv)
{
- // Storage for return values, plus one slot for a temp int (see below).
- int[] xy;
-
if (b == 0)
throw new ArithmeticException("not invertible");
- else if (b == 1)
- {
+
+ if (b == 1)
// Success: values are indeed invertible!
// Bottom of the recursion reached; start unwinding.
- xy = new int[3];
- xy[0] = -prevDiv;
- xy[1] = 1;
- return xy;
- }
+ return new int[] { -prevDiv, 1 };
- xy = euclidInv(b, a % b, a / b); // Recursion happens here.
-
- // xy[2] is just temp storage for intermediate results in the following
- // calculation. This saves us a bit of space over having an int
- // allocated at every level of this recursive method.
- xy[2] = xy[0];
- xy[0] = xy[2] * -prevDiv + xy[1];
- xy[1] = xy[2];
+ int[] xy = euclidInv(b, a % b, a / b); // Recursion happens here.
+ a = xy[0]; // use our local copy of 'a' as a work var
+ xy[0] = a * -prevDiv + xy[1];
+ xy[1] = a;
return xy;
}
- private static final BigInteger[]
- euclidInv(BigInteger a, BigInteger b, BigInteger prevDiv)
+ private static final void euclidInv(BigInteger a, BigInteger b,
+ BigInteger prevDiv, BigInteger xy0,
+ BigInteger xy1, BigInteger xy2)
{
- // FIXME: This method could be more efficient memory-wise and should be
- // modified as such since it is recursive.
-
- // Storage for return values, plus one slot for a temp int (see below).
- BigInteger[] xy;
-
if (b.isZero())
throw new ArithmeticException("not invertible");
- else if (b.isOne())
+
+ if (b.isOne())
{
// Success: values are indeed invertible!
// Bottom of the recursion reached; start unwinding.
- xy = new BigInteger[3];
- xy[0] = neg(prevDiv);
- xy[1] = ONE;
- return xy;
+ // WARNING: xy1 is, and xy0 may be, a shared BI!
+ xy0 = neg(prevDiv);
+ xy1 = ONE;
+ return;
}
// Recursion happens in the following conditional!
@@ -1104,9 +1038,8 @@
if (a.words == null)
{
int[] xyInt = euclidInv(b.ival, a.ival % b.ival, a.ival / b.ival);
- xy = new BigInteger[3];
- xy[0] = new BigInteger(xyInt[0]);
- xy[1] = new BigInteger(xyInt[1]);
+ xy0 = new BigInteger(xyInt[0]); // non-shared BI
+ xy1 = new BigInteger(xyInt[1]); // non-shared BI
}
else
{
@@ -1116,16 +1049,15 @@
// quot and rem may not be in canonical form. ensure
rem.canonicalize();
quot.canonicalize();
- xy = euclidInv(b, rem, quot);
+ euclidInv(b, rem, quot, xy0, xy1, xy2);
}
- // xy[2] is just temp storage for intermediate results in the following
+ // xy2 is just temp storage for intermediate results in the following
// calculation. This saves us a bit of space over having a BigInteger
// allocated at every level of this recursive method.
- xy[2] = xy[0];
- xy[0] = add(xy[1], times(xy[2], prevDiv), -1);
- xy[1] = xy[2];
- return xy;
+ xy2 = xy0;
+ xy0 = add(xy1, times(xy2, prevDiv), -1);
+ xy1 = xy2;
}
public BigInteger modInverse(BigInteger y)
@@ -1136,7 +1068,7 @@
// Degenerate cases.
if (y.isOne())
return ZERO;
- else if (isOne())
+ if (isOne())
return ONE;
// Use Euclid's algorithm as in gcd() but do this recursively
@@ -1144,8 +1076,6 @@
// unwind from the recursion.
// Used http://www.math.nmsu.edu/~crypto/EuclideanAlgo.html as reference.
BigInteger result = new BigInteger();
- int xval = ival;
- int yval = y.ival;
boolean swapped = false;
if (y.words == null)
@@ -1156,8 +1086,8 @@
// math. Note that BigInteger.mod() must be used even if this is
// already an int as the % operator would provide a negative result if
// this is negative, BigInteger.mod() never returns negative values.
- if (words != null || isNegative())
- xval = mod(y).ival;
+ int xval = (words != null || isNegative()) ? mod(y).ival : ival;
+ int yval = y.ival;
// Swap values so x > y.
if (yval > xval)
@@ -1178,16 +1108,13 @@
}
else
{
- BigInteger x = this;
-
// As above, force this to be a positive value via modulo math.
- if (isNegative())
- x = mod(y);
+ BigInteger x = isNegative() ? this.mod(y) : this;
// Swap values so x > y.
if (x.compareTo(y) < 0)
{
- BigInteger tmp = x; x = y; y = tmp;
+ result = x; x = y; y = result; // use 'result' as a work var
swapped = true;
}
// As above (for ints), result will be in the 2nd element unless
@@ -1198,7 +1125,10 @@
// quot and rem may not be in canonical form. ensure
rem.canonicalize();
quot.canonicalize();
- result = euclidInv(y, rem, quot)[swapped ? 0 : 1];
+ BigInteger xy0 = new BigInteger();
+ BigInteger xy1 = new BigInteger();
+ euclidInv(y, rem, quot, xy0, xy1, result);
+ result = swapped ? xy0 : xy1;
// Result can't be negative, so make it positive by adding the
// original modulus, y (which is now x if they were swapped).
@@ -1222,16 +1152,13 @@
// To do this naively by first raising this to the power of exponent
// and then performing modulo m would be extremely expensive, especially
// for very large numbers. The solution is found in Number Theory
- // where a combination of partial powers and modulos can be done easily.
+ // where a combination of partial powers and moduli can be done easily.
//
// We'll use the algorithm for Additive Chaining which can be found on
// p. 244 of "Applied Cryptography, Second Edition" by Bruce Schneier.
- BigInteger s, t, u;
- int i;
-
- s = ONE;
- t = this;
- u = exponent;
+ BigInteger s = ONE;
+ BigInteger t = this;
+ BigInteger u = exponent;
while (!u.isZero())
{
@@ -1248,24 +1175,22 @@
private static final int gcd(int a, int b)
{
// Euclid's algorithm, copied from libg++.
+ int tmp;
if (b > a)
{
- int tmp = a; a = b; b = tmp;
+ tmp = a; a = b; b = tmp;
}
for(;;)
{
if (b == 0)
return a;
- else if (b == 1)
+ if (b == 1)
return b;
- else
- {
- int tmp = b;
+ tmp = b;
b = a % b;
a = tmp;
}
}
- }
public BigInteger gcd(BigInteger y)
{
@@ -1274,7 +1199,7 @@
if (words == null)
{
if (xval == 0)
- return BigInteger.abs(y);
+ return abs(y);
if (y.words == null
&& xval != Integer.MIN_VALUE && yval != Integer.MIN_VALUE)
{
@@ -1282,14 +1207,14 @@
xval = -xval;
if (yval < 0)
yval = -yval;
- return BigInteger.make(BigInteger.gcd(xval, yval));
+ return valueOf(gcd(xval, yval));
}
xval = 1;
}
if (y.words == null)
{
if (yval == 0)
- return BigInteger.abs(this);
+ return abs(this);
yval = 1;
}
int len = (xval > yval ? xval : yval) + 1;
@@ -1304,8 +1229,24 @@
return result.canonicalize();
}
+ /**
+ * <p>Returns <code>true</code> if this BigInteger is probably prime,
+ * <code>false</code> if it's definitely composite. If <code>certainty</code>
+ * is <code><= 0</code>, <code>true</code> is returned.</p>
+ *
+ * @param certainty a measure of the uncertainty that the caller is willing
+ * to tolerate: if the call returns <code>true</code> the probability that
+ * this BigInteger is prime exceeds <code>(1 - 1/2<sup>certainty</sup>)</code>.
+ * The execution time of this method is proportional to the value of this
+ * parameter.
+ * @return <code>true</code> if this BigInteger is probably prime,
+ * <code>false</code> if it's definitely composite.
+ */
public boolean isProbablePrime(int certainty)
{
+ if (certainty < 1)
+ return true;
+
/** We'll use the Rabin-Miller algorithm for doing a probabilistic
* primality test. It is fast, easy and has faster decreasing odds of a
* composite passing than with other tests. This means that this
@@ -1317,19 +1258,20 @@
* Cryptography, Second Edition" by Bruce Schneier.
*/
- // First rule out small prime factors and assure the number is odd.
- for (int i = 0; i < primes.length; i++)
+ // First rule out small prime factors
+ BigInteger rem = new BigInteger();
+ int i;
+ for (i = 0; i < primes.length; i++)
{
if (words == null && ival == primes[i])
return true;
- if (remainder(make(primes[i])).isZero())
+
+ divide(this, smallFixNums[primes[i] - minFixNum], null, rem, TRUNCATE);
+ if (rem.canonicalize().isZero())
return false;
}
// Now perform the Rabin-Miller test.
- // NB: I know that this can be simplified programatically, but
- // I have tried to keep it as close as possible to the algorithm
- // as written in the Schneier book for reference purposes.
// Set b to the number of times 2 evenly divides (this - 1).
// I.e. 2^b is the largest power of 2 that divides (this - 1).
@@ -1337,22 +1279,31 @@
int b = pMinus1.getLowestSetBit();
// Set m such that this = 1 + 2^b * m.
- BigInteger m = pMinus1.divide(make(2L << b - 1));
-
- Random rand = new Random();
- while (certainty-- > 0)
- {
- // Pick a random number greater than 1 and less than this.
- // The algorithm says to pick a small number to make the calculations
- // go faster, but it doesn't say how small; we'll use 2 to 1024.
- int a = rand.nextInt();
- a = (a < 0 ? -a : a) % 1023 + 2;
+ BigInteger m = pMinus1.divide(valueOf(2L << b - 1));
- BigInteger z = make(a).modPow(m, this);
+ // The HAC (Handbook of Applied Cryptography), Alfred Menezes & al. Note
+ // 4.49 (controlling the error probability) gives the number of trials
+ // for an error probability of 1/2**80, given the number of bits in the
+ // number to test. we shall use these numbers as is if/when 'certainty'
+ // is less or equal to 80, and twice as much if it's greater.
+ int bits = this.bitLength();
+ for (i = 0; i < k.length; i++)
+ if (bits <= k[i])
+ break;
+ int trials = t[i];
+ if (certainty > 80)
+ trials *= 2;
+ BigInteger z;
+ for (int t = 0; t < trials; t++)
+ {
+ // The HAC (Handbook of Applied Cryptography), Alfred Menezes & al.
+ // Remark 4.28 states: "...A strategy that is sometimes employed
+ // is to fix the bases a to be the first few primes instead of
+ // choosing them at random.
+ z = smallFixNums[primes[t] - minFixNum].modPow(m, this);
if (z.isOne() || z.equals(pMinus1))
continue; // Passes the test; may be prime.
- int i;
for (i = 0; i < b; )
{
if (z.isOne())
@@ -1361,7 +1312,7 @@
if (z.equals(pMinus1))
break; // Passes the test; may be prime.
- z = z.modPow(make(2), this);
+ z = z.modPow(valueOf(2), this);
}
if (i == b && !z.equals(pMinus1))
@@ -1462,9 +1413,9 @@
if (x.words == null)
{
if (count <= 0)
- return make(count > -32 ? x.ival >> (-count) : x.ival < 0 ? -1 : 0);
+ return valueOf(count > -32 ? x.ival >> (-count) : x.ival < 0 ? -1 : 0);
if (count < 32)
- return make((long) x.ival << count);
+ return valueOf((long) x.ival << count);
}
if (count == 0)
return x;
@@ -1502,7 +1453,6 @@
work = words;
int len = ival;
- int buf_size = len * (MPN.chars_per_word(radix) + 1);
if (radix == 16)
{
if (neg)
@@ -1555,7 +1505,7 @@
{
if (words == null)
return Integer.toString(ival, radix);
- else if (ival <= 2)
+ if (ival <= 2)
return Long.toString(longValue(), radix);
int buf_size = ival * (MPN.chars_per_word(radix) + 1);
StringBuffer buffer = new StringBuffer(buf_size);
@@ -1605,7 +1555,7 @@
{
if (obj == null || ! (obj instanceof BigInteger))
return false;
- return BigInteger.equals(this, (BigInteger) obj);
+ return equals(this, (BigInteger) obj);
}
private static BigInteger valueOf(String s, int radix)
@@ -1615,7 +1565,7 @@
// Testing (len < MPN.chars_per_word(radix)) would be more accurate,
// but slightly more expensive, for little practical gain.
if (len <= 15 && radix <= 16)
- return BigInteger.make(Long.parseLong(s, radix));
+ return valueOf(Long.parseLong(s, radix));
int byte_len = 0;
byte[] bytes = new byte[len];
@@ -1660,8 +1610,7 @@
if (ival <= 2)
return (double) longValue();
if (isNegative())
- return BigInteger.neg(this).roundToDouble(0, true, false);
- else
+ return neg(this).roundToDouble(0, true, false);
return roundToDouble(0, false, false);
}
@@ -1769,7 +1718,6 @@
* Assumes words.length >= (this.words == null ? 1 : this.ival).
* Result is zero-extended, but need not be a valid 2's complement number.
*/
-
private void getAbsolute(int[] words)
{
int len;
@@ -1820,7 +1768,7 @@
return;
}
realloc(len + 1);
- if (BigInteger.negate(words, x.words, len))
+ if (negate(words, x.words, len))
words[len++] = 0;
ival = len;
}
@@ -1844,7 +1792,7 @@
private static BigInteger neg(BigInteger x)
{
if (x.words == null && x.ival != Integer.MIN_VALUE)
- return make(- x.ival);
+ return valueOf(- x.ival);
BigInteger result = new BigInteger(0);
result.setNegative(x);
return result.canonicalize();
@@ -1852,7 +1800,7 @@
public BigInteger negate()
{
- return BigInteger.neg(this);
+ return neg(this);
}
/** Calculates ceiling(log2(this < 0 ? -this : this+1))
@@ -1862,7 +1810,6 @@
{
if (words == null)
return MPN.intLength(ival);
- else
return MPN.intLength(words, ival);
}
@@ -1913,7 +1860,7 @@
case 1: return x.and(y);
case 3: return x;
case 5: return y;
- case 15: return make(-1);
+ case 15: return valueOf(-1);
}
BigInteger result = new BigInteger();
setBitOp(result, op, x, y);
@@ -2111,15 +2058,15 @@
private static BigInteger and(BigInteger x, int y)
{
if (x.words == null)
- return BigInteger.make(x.ival & y);
+ return valueOf(x.ival & y);
if (y >= 0)
- return BigInteger.make(x.words[0] & y);
+ return valueOf(x.words[0] & y);
int len = x.ival;
int[] words = new int[len];
words[0] = x.words[0] & y;
while (--len > 0)
words[len] = x.words[len];
- return BigInteger.make(words, x.ival);
+ return make(words, x.ival);
}
/** Return the logical (bit-wise) "and" of two BigIntegers. */
@@ -2142,7 +2089,7 @@
words[i] = x.words[i] & y.words[i];
for ( ; i < len; i++)
words[i] = x.words[i];
- return BigInteger.make(words, len);
+ return make(words, len);
}
/** Return the logical (bit-wise) "(inclusive) or" of two BigIntegers. */