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;