summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/java/math/BigInteger.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/java/math/BigInteger.java')
-rw-r--r--libjava/classpath/java/math/BigInteger.java78
1 files changed, 48 insertions, 30 deletions
diff --git a/libjava/classpath/java/math/BigInteger.java b/libjava/classpath/java/math/BigInteger.java
index b57cf607e34..c897d8bf48d 100644
--- a/libjava/classpath/java/math/BigInteger.java
+++ b/libjava/classpath/java/math/BigInteger.java
@@ -1,5 +1,5 @@
/* java.math.BigInteger -- Arbitary precision integers
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -57,7 +57,7 @@ import java.util.Random;
* @date December 20, 1999.
* @status believed complete and correct.
*/
-public class BigInteger extends Number implements Comparable
+public class BigInteger extends Number implements Comparable<BigInteger>
{
/** All integers are stored in 2's-complement form.
* If words == null, the ival is the value of this BigInteger.
@@ -83,7 +83,8 @@ public class BigInteger extends Number implements Comparable
private static final int numFixNum = maxFixNum-minFixNum+1;
private static final BigInteger[] smallFixNums = new BigInteger[numFixNum];
- static {
+ static
+ {
for (int i = numFixNum; --i >= 0; )
smallFixNums[i] = new BigInteger(i + minFixNum);
}
@@ -92,14 +93,14 @@ public class BigInteger extends Number implements Comparable
* The constant zero as a BigInteger.
* @since 1.2
*/
- public static final BigInteger ZERO = smallFixNums[-minFixNum];
+ public static final BigInteger ZERO = smallFixNums[0 - minFixNum];
/**
* The constant one as a BigInteger.
* @since 1.2
*/
public static final BigInteger ONE = smallFixNums[1 - minFixNum];
-
+
/**
* The constant ten as a BigInteger.
* @since 1.5
@@ -197,8 +198,20 @@ public class BigInteger extends Number implements Comparable
private void init(int numBits, Random rnd)
{
int highbits = numBits & 31;
+ // minimum number of bytes to store the above number of bits
+ int highBitByteCount = (highbits + 7) / 8;
+ // number of bits to discard from the last byte
+ int discardedBitCount = highbits % 8;
+ if (discardedBitCount != 0)
+ discardedBitCount = 8 - discardedBitCount;
+ byte[] highBitBytes = new byte[highBitByteCount];
if (highbits > 0)
- highbits = rnd.nextInt() >>> (32 - highbits);
+ {
+ rnd.nextBytes(highBitBytes);
+ highbits = (highBitBytes[highBitByteCount - 1] & 0xFF) >>> discardedBitCount;
+ for (int i = highBitByteCount - 2; i >= 0; i--)
+ highbits = (highbits << 8) | (highBitBytes[i] & 0xFF);
+ }
int nwords = numBits / 32;
while (highbits == 0 && nwords > 0)
@@ -225,8 +238,13 @@ public class BigInteger extends Number implements Comparable
this(bitLength, rnd);
// Keep going until we find a probable prime.
+ BigInteger result;
while (true)
{
+ // ...but first ensure that BI has bitLength bits
+ result = setBit(bitLength - 1);
+ this.ival = result.ival;
+ this.words = result.words;
if (isProbablePrime(certainty))
return;
@@ -377,14 +395,7 @@ public class BigInteger extends Number implements Comparable
return MPN.cmp(x.words, y.words, x_len);
}
- // JDK1.2
- public int compareTo(Object obj)
- {
- if (obj instanceof BigInteger)
- return compareTo(this, (BigInteger) obj);
- throw new ClassCastException();
- }
-
+ /** @since 1.2 */
public int compareTo(BigInteger val)
{
return compareTo(this, val);
@@ -1589,24 +1600,31 @@ public class BigInteger extends Number implements Comparable
// but slightly more expensive, for little practical gain.
if (len <= 15 && radix <= 16)
return valueOf(Long.parseLong(s, radix));
-
+
+ int i, digit;
+ boolean negative;
+ byte[] bytes;
+ char ch = s.charAt(0);
+ if (ch == '-')
+ {
+ negative = true;
+ i = 1;
+ bytes = new byte[len - 1];
+ }
+ else
+ {
+ negative = false;
+ i = 0;
+ bytes = new byte[len];
+ }
int byte_len = 0;
- byte[] bytes = new byte[len];
- boolean negative = false;
- for (int i = 0; i < len; i++)
+ for ( ; i < len; i++)
{
- char ch = s.charAt(i);
- if (ch == '-')
- negative = true;
- else if (ch == '_' || (byte_len == 0 && (ch == ' ' || ch == '\t')))
- continue;
- else
- {
- int digit = Character.digit(ch, radix);
- if (digit < 0)
- break;
- bytes[byte_len++] = (byte) digit;
- }
+ ch = s.charAt(i);
+ digit = Character.digit(ch, radix);
+ if (digit < 0)
+ throw new NumberFormatException();
+ bytes[byte_len++] = (byte) digit;
}
return valueOf(bytes, byte_len, negative, radix);
}
OpenPOWER on IntegriCloud