src/share/classes/java/math/BigInteger.java
Print this page
rev 9307 : 8035279: Clean up internal deprecations in BigInteger
Summary: Modify lazily intialized values to use different marker values.
Reviewed-by: TBD
*** 145,198 ****
// These "redundant fields" are initialized with recognizable nonsense
// values, and cached the first time they are needed (or never, if they
// aren't needed).
/**
! * One plus the bitCount of this BigInteger. Zeros means unitialized.
*
* @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;
/**
! * One plus the bitLength of this BigInteger. Zeros means unitialized.
! * (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;
/**
! * Two plus the lowest set bit of this BigInteger, as returned by
! * getLowestSetBit().
*
* @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;
/**
! * 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
* 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.
*/
! @Deprecated
! private int firstNonzeroIntNum;
/**
* This mask is used to obtain the value of an int as if it were unsigned.
*/
final static long LONG_MASK = 0xffffffffL;
--- 145,189 ----
// 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 bitCount of this BigInteger. {@code Integer.MIN_VALUE} means
! * uninitialized.
*
* @serial
* @see #bitCount
*/
! private volatile int bitCount = Integer.MIN_VALUE;
/**
! * The bitLength of this BigInteger. {@code Integer.MIN_VALUE} means
! * uninitialized.
*
* @serial
* @see #bitLength()
*/
! private volatile int bitLength = Integer.MIN_VALUE;
/**
! * The lowest set bit of this BigInteger, as returned by
! * getLowestSetBit(). {@code Integer.MIN_VALUE} means uninitialized,
! * and {@code -1} that this BigInteger contains no one bits.
*
* @serial
* @see #getLowestSetBit
*/
! private volatile int lowestSetBit = Integer.MIN_VALUE;
/**
! * The index of the lowest-order int in the magnitude of this
! * BigInteger that contains a nonzero int, or {@code Integer.MIN_VALUE} to
! * indicate uninitialized (either value is acceptable).
* The least significant int has int-number 0, the next int in order of
* increasing significance has int-number 1, and so forth.
*/
! private volatile int firstNonzeroIntNum = Integer.MIN_VALUE;
/**
* This mask is used to obtain the value of an int as if it were unsigned.
*/
final static long LONG_MASK = 0xffffffffL;
*** 3238,3262 ****
* (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;
! if (lsb == -2) { // lowestSetBit not initialized yet
! lsb = 0;
if (signum == 0) {
lsb -= 1;
} else {
// Search for lowest order nonzero int
int i,b;
for (i=0; (b = getInt(i)) == 0; i++)
;
lsb += (i << 5) + Integer.numberOfTrailingZeros(b);
}
! lowestSetBit = lsb + 2;
}
! return lsb;
}
// Miscellaneous Bit Operations
--- 3229,3253 ----
* (Computes {@code (this == 0? -1 : log2(this & -this))}.)
*
* @return index of the rightmost one bit in this BigInteger.
*/
public int getLowestSetBit() {
! // This computation has a known, acceptable non-critical race condition.
! if (lowestSetBit == Integer.MIN_VALUE) { // lowestSetBit not initialized yet
! int lsb = 0;
if (signum == 0) {
lsb -= 1;
} else {
// Search for lowest order nonzero int
int i,b;
for (i=0; (b = getInt(i)) == 0; i++)
;
lsb += (i << 5) + Integer.numberOfTrailingZeros(b);
}
! lowestSetBit = lsb;
}
! return lowestSetBit;
}
// Miscellaneous Bit Operations
*** 3269,3301 ****
*
* @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;
! if (n == -1) { // bitLength not initialized yet
int[] m = mag;
int len = m.length;
! if (len == 0) {
! n = 0; // offset by one to initialize
! } else {
// Calculate the bit length of the magnitude
int magBitLength = ((len - 1) << 5) + bitLengthForInt(mag[0]);
if (signum < 0) {
// Check if magnitude is a power of two
boolean pow2 = (Integer.bitCount(mag[0]) == 1);
! for (int i=1; i< len && pow2; i++)
pow2 = (mag[i] == 0);
! n = (pow2 ? magBitLength -1 : magBitLength);
} else {
n = magBitLength;
}
}
! bitLength = n + 1;
}
! return n;
}
/**
* Returns the number of bits in the two's complement representation
* of this BigInteger that differ from its sign bit. This method is
--- 3260,3292 ----
*
* @return number of bits in the minimal two's-complement
* representation of this BigInteger, <i>excluding</i> a sign bit.
*/
public int bitLength() {
! // This computation has a known, acceptable non-critical race condition.
! if (bitLength == Integer.MIN_VALUE) { // bitLength not initialized yet
int[] m = mag;
int len = m.length;
! int n = 0;
! if (len != 0) {
// Calculate the bit length of the magnitude
int magBitLength = ((len - 1) << 5) + bitLengthForInt(mag[0]);
if (signum < 0) {
// Check if magnitude is a power of two
boolean pow2 = (Integer.bitCount(mag[0]) == 1);
! for (int i = 1; i < len && pow2; i++) {
pow2 = (mag[i] == 0);
+ }
! n = (pow2 ? magBitLength - 1 : magBitLength);
} else {
n = magBitLength;
}
}
! bitLength = n;
}
! return bitLength;
}
/**
* Returns the number of bits in the two's complement representation
* of this BigInteger that differ from its sign bit. This method is
*** 3303,3315 ****
*
* @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;
! 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]);
if (signum < 0) {
// Count the trailing zeros in the magnitude
--- 3294,3306 ----
*
* @return number of bits in the two's complement representation
* of this BigInteger that differ from its sign bit.
*/
public int bitCount() {
! // This computation has a known, acceptable non-critical race condition.
! if (bitCount == Integer.MIN_VALUE) { // bitCount not initialized yet
! int bc = 0;
// Count the bits in the magnitude
for (int i=0; i < mag.length; i++)
bc += Integer.bitCount(mag[i]);
if (signum < 0) {
// Count the trailing zeros in the magnitude
*** 3317,3329 ****
for (j=mag.length-1; mag[j] == 0; j--)
magTrailingZeroCount += 32;
magTrailingZeroCount += Integer.numberOfTrailingZeros(mag[j]);
bc += magTrailingZeroCount - 1;
}
! bitCount = bc + 1;
}
! return bc;
}
// Primality Testing
/**
--- 3308,3320 ----
for (j=mag.length-1; mag[j] == 0; j--)
magTrailingZeroCount += 32;
magTrailingZeroCount += Integer.numberOfTrailingZeros(mag[j]);
bc += magTrailingZeroCount - 1;
}
! bitCount = bc;
}
! return bitCount;
}
// Primality Testing
/**
*** 4188,4210 ****
* 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.
*/
private int firstNonzeroIntNum() {
! int fn = firstNonzeroIntNum - 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
}
! return fn;
}
/** use serialVersionUID from JDK 1.1. for interoperability */
private static final long serialVersionUID = -8287574255936472291L;
--- 4179,4201 ----
* 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.
*/
private int firstNonzeroIntNum() {
! // This computation has a known, acceptable non-critical race condition.
! if (firstNonzeroIntNum == Integer.MIN_VALUE) { // firstNonzeroIntNum not initialized yet
! int 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;
}
! return firstNonzeroIntNum;
}
/** use serialVersionUID from JDK 1.1. for interoperability */
private static final long serialVersionUID = -8287574255936472291L;
*** 4236,4250 ****
* 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.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
/*
* In order to maintain compatibility with previous serialized forms,
--- 4227,4240 ----
* 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 explicitly to initialize the cache fields
! * bitCount, bitLength, firstNonzeroIntNum, and lowestSetBit to
! * Integer.MIN_VALUE. This serves to indicate that the actual values need
! * to be calculated when accessed.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
/*
* In order to maintain compatibility with previous serialized forms,
*** 4286,4295 ****
--- 4276,4291 ----
checkRange();
} catch (ArithmeticException e) {
throw new java.io.StreamCorruptedException("BigInteger: Out of the supported range");
}
}
+
+ // Initialize cached fields to indicate not computed yet.
+ bitCount = Integer.MIN_VALUE;
+ bitLength = Integer.MIN_VALUE;
+ lowestSetBit = Integer.MIN_VALUE;
+ firstNonzeroIntNum = Integer.MIN_VALUE;
}
// Support for resetting final fields while deserializing
private static class UnsafeHolder {
private static final sun.misc.Unsafe unsafe;