src/share/classes/java/math/BigInteger.java
Print this page
rev 9365 : 8035279: Clean up internal deprecations in BigInteger
Summary: Rename pertinent private instance variables to describe what they actually represent.
Reviewed-by: psandoz, smarks
@@ -124,12 +124,10 @@
/**
* The signum of this BigInteger: -1 for negative, 0 for zero, or
* 1 for positive. Note that the BigInteger zero <i>must</i> have
* a signum of 0. This is necessary to ensures that there is exactly one
* representation for each BigInteger value.
- *
- * @serial
*/
final int signum;
/**
* The magnitude of this BigInteger, in <i>big-endian</i> order: the
@@ -140,59 +138,47 @@
* value. Note that this implies that the BigInteger zero has a
* zero-length mag array.
*/
final int[] mag;
- // These "redundant fields" are initialized with recognizable nonsense
- // values, and cached the first time they are needed (or never, if they
- // aren't needed).
+ // The following fields are stable variables. A stable variable's value
+ // changes at most once from the default zero value to a non-zero stable
+ // value. A stable value is calculated lazily on demand.
/**
- * One plus the bitCount of this BigInteger. Zeros means unitialized.
+ * One plus the bitCount of this BigInteger. This is a stable variable.
*
- * @serial
* @see #bitCount
- * @deprecated Deprecated since logical value is offset from stored
- * value and correction factor is applied in accessor method.
*/
- @Deprecated
- private int bitCount;
+ private int bitCountPlusOne;
/**
- * One plus the bitLength of this BigInteger. Zeros means unitialized.
+ * One plus the bitLength of this BigInteger. This is a stable variable.
* (either value is acceptable).
*
- * @serial
* @see #bitLength()
- * @deprecated Deprecated since logical value is offset from stored
- * value and correction factor is applied in accessor method.
*/
- @Deprecated
- private int bitLength;
+ private int bitLengthPlusOne;
/**
- * Two plus the lowest set bit of this BigInteger, as returned by
- * getLowestSetBit().
+ * Two plus the lowest set bit of this BigInteger. This is a stable variable.
*
- * @serial
* @see #getLowestSetBit
- * @deprecated Deprecated since logical value is offset from stored
- * value and correction factor is applied in accessor method.
*/
- @Deprecated
- private int lowestSetBit;
+ private int lowestSetBitPlusTwo;
/**
* Two plus the index of the lowest-order int in the magnitude of this
- * BigInteger that contains a nonzero int, or -2 (either value is acceptable).
- * The least significant int has int-number 0, the next int in order of
+ * BigInteger that contains a nonzero int. This is a stable variable. The
+ * least significant int has int-number 0, the next int in order of
* increasing significance has int-number 1, and so forth.
- * @deprecated Deprecated since logical value is offset from stored
- * value and correction factor is applied in accessor method.
+ *
+ * <p>Note: never used for a BigInteger with a magnitude of zero.
+ *
+ * @see #firstNonzeroIntNum()
*/
- @Deprecated
- private int firstNonzeroIntNum;
+ private int firstNonzeroIntNumPlusTwo;
/**
* This mask is used to obtain the value of an int as if it were unsigned.
*/
final static long LONG_MASK = 0xffffffffL;
@@ -3238,11 +3224,11 @@
* (Computes {@code (this == 0? -1 : log2(this & -this))}.)
*
* @return index of the rightmost one bit in this BigInteger.
*/
public int getLowestSetBit() {
- @SuppressWarnings("deprecation") int lsb = lowestSetBit - 2;
+ int lsb = lowestSetBitPlusTwo - 2;
if (lsb == -2) { // lowestSetBit not initialized yet
lsb = 0;
if (signum == 0) {
lsb -= 1;
} else {
@@ -3250,11 +3236,11 @@
int i,b;
for (i=0; (b = getInt(i)) == 0; i++)
;
lsb += (i << 5) + Integer.numberOfTrailingZeros(b);
}
- lowestSetBit = lsb + 2;
+ lowestSetBitPlusTwo = lsb + 2;
}
return lsb;
}
@@ -3269,11 +3255,11 @@
*
* @return number of bits in the minimal two's-complement
* representation of this BigInteger, <i>excluding</i> a sign bit.
*/
public int bitLength() {
- @SuppressWarnings("deprecation") int n = bitLength - 1;
+ int n = bitLengthPlusOne - 1;
if (n == -1) { // bitLength not initialized yet
int[] m = mag;
int len = m.length;
if (len == 0) {
n = 0; // offset by one to initialize
@@ -3289,11 +3275,11 @@
n = (pow2 ? magBitLength -1 : magBitLength);
} else {
n = magBitLength;
}
}
- bitLength = n + 1;
+ bitLengthPlusOne = n + 1;
}
return n;
}
/**
@@ -3303,11 +3289,11 @@
*
* @return number of bits in the two's complement representation
* of this BigInteger that differ from its sign bit.
*/
public int bitCount() {
- @SuppressWarnings("deprecation") int bc = bitCount - 1;
+ int bc = bitCountPlusOne - 1;
if (bc == -1) { // bitCount not initialized yet
bc = 0; // offset by one to initialize
// Count the bits in the magnitude
for (int i=0; i < mag.length; i++)
bc += Integer.bitCount(mag[i]);
@@ -3317,11 +3303,11 @@
for (j=mag.length-1; mag[j] == 0; j--)
magTrailingZeroCount += 32;
magTrailingZeroCount += Integer.numberOfTrailingZeros(mag[j]);
bc += magTrailingZeroCount - 1;
}
- bitCount = bc + 1;
+ bitCountPlusOne = bc + 1;
}
return bc;
}
// Primality Testing
@@ -3620,20 +3606,20 @@
* @param radix The base to convert to.
* @param digits The minimum number of digits to pad to.
*/
private static void toString(BigInteger u, StringBuilder sb, int radix,
int digits) {
- /* If we're smaller than a certain threshold, use the smallToString
- method, padding with leading zeroes when necessary. */
+ // If we're smaller than a certain threshold, use the smallToString
+ // method, padding with leading zeroes when necessary.
if (u.mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD) {
String s = u.smallToString(radix);
// Pad with internal zeros if necessary.
// Don't pad if we're at the beginning of the string.
if ((s.length() < digits) && (sb.length() > 0)) {
- for (int i=s.length(); i < digits; i++) { // May be a faster way to
- sb.append('0'); // do this?
+ for (int i=s.length(); i < digits; i++) {
+ sb.append('0');
}
}
sb.append(s);
return;
@@ -4186,23 +4172,24 @@
/**
* Returns the index of the int that contains the first nonzero int in the
* little-endian binary representation of the magnitude (int 0 is the
* least significant). If the magnitude is zero, return value is undefined.
+ *
+ * <p>Note: never used for a BigInteger with a magnitude of zero.
+ * @see #getInt.
*/
private int firstNonzeroIntNum() {
- int fn = firstNonzeroIntNum - 2;
+ int fn = firstNonzeroIntNumPlusTwo - 2;
if (fn == -2) { // firstNonzeroIntNum not initialized yet
- fn = 0;
-
// Search for the first nonzero int
int i;
int mlen = mag.length;
for (i = mlen - 1; i >= 0 && mag[i] == 0; i--)
;
fn = mlen - i - 1;
- firstNonzeroIntNum = fn + 2; // offset by two to initialize
+ firstNonzeroIntNumPlusTwo = fn + 2; // offset by two to initialize
}
return fn;
}
/** use serialVersionUID from JDK 1.1. for interoperability */
@@ -4210,20 +4197,21 @@
/**
* Serializable fields for BigInteger.
*
* @serialField signum int
- * signum of this BigInteger.
+ * signum of this BigInteger
* @serialField magnitude int[]
- * magnitude array of this BigInteger.
+ * magnitude array of this BigInteger
* @serialField bitCount int
- * number of bits in this BigInteger
+ * appears in the serialized for backward compatibility
* @serialField bitLength int
- * the number of bits in the minimal two's-complement
- * representation of this BigInteger
+ * appears in the serialized for backward compatibility
+ * @serialField firstNonzeroByteNum int
+ * appears in the serialized for backward compatibility
* @serialField lowestSetBit int
- * lowest set bit in the twos complement representation
+ * appears in the serialized for backward compatibility
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("signum", Integer.TYPE),
new ObjectStreamField("magnitude", byte[].class),
new ObjectStreamField("bitCount", Integer.TYPE),
@@ -4236,26 +4224,18 @@
* Reconstitute the {@code BigInteger} instance from a stream (that is,
* deserialize it). The magnitude is read in as an array of bytes
* for historical reasons, but it is converted to an array of ints
* and the byte array is discarded.
* Note:
- * The current convention is to initialize the cache fields, bitCount,
- * bitLength and lowestSetBit, to 0 rather than some other marker value.
- * Therefore, no explicit action to set these fields needs to be taken in
- * readObject because those fields already have a 0 value be default since
- * defaultReadObject is not being used.
+ * The current convention is to initialize the cache fields, bitCountPlusOne,
+ * bitLengthPlusOne and lowestSetBitPlusTwo, to 0 rather than some other
+ * marker value. Therefore, no explicit action to set these fields needs to
+ * be taken in readObject because those fields already have a 0 value by
+ * default since defaultReadObject is not being used.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
- /*
- * In order to maintain compatibility with previous serialized forms,
- * the magnitude of a BigInteger is serialized as an array of bytes.
- * The magnitude field is used as a temporary store for the byte array
- * that is deserialized. The cached computation fields should be
- * transient but are serialized for compatibility reasons.
- */
-
// prepare to read the alternate persistent fields
ObjectInputStream.GetField fields = s.readFields();
// Read the alternate persistent fields that we care about
int sign = fields.get("signum", -2);
@@ -4315,16 +4295,17 @@
unsafe.putObjectVolatile(bi, magOffset, magnitude);
}
}
/**
- * Save the {@code BigInteger} instance to a stream.
- * The magnitude of a BigInteger is serialized as a byte array for
- * historical reasons.
- *
- * @serialData two necessary fields are written as well as obsolete
- * fields for compatibility with older versions.
+ * Save the {@code BigInteger} instance to a stream. The magnitude of a
+ * {@code BigInteger} is serialized as a byte array for historical reasons.
+ * To maintain compatibility with older implementations, the integers
+ * -1, -1, -2, and -2 are written as the values of the obsolete fields
+ * {@code bitCount}, {@code bitLength}, {@code lowestSetBit}, and
+ * {@code firstNonzeroByteNum}, respectively; current implementations will
+ * ignore these values.
*/
private void writeObject(ObjectOutputStream s) throws IOException {
// set the values of the Serializable fields
ObjectOutputStream.PutField fields = s.putFields();
fields.put("signum", signum);