< prev index next >

src/java.base/share/classes/java/math/BigInteger.java

Print this page




4587     * least significant). If the magnitude is zero, return value is undefined.
4588     *
4589     * <p>Note: never used for a BigInteger with a magnitude of zero.
4590     * @see #getInt.
4591     */
4592     private int firstNonzeroIntNum() {
4593         int fn = firstNonzeroIntNumPlusTwo - 2;
4594         if (fn == -2) { // firstNonzeroIntNum not initialized yet
4595             // Search for the first nonzero int
4596             int i;
4597             int mlen = mag.length;
4598             for (i = mlen - 1; i >= 0 && mag[i] == 0; i--)
4599                 ;
4600             fn = mlen - i - 1;
4601             firstNonzeroIntNumPlusTwo = fn + 2; // offset by two to initialize
4602         }
4603         return fn;
4604     }
4605 
4606     /** use serialVersionUID from JDK 1.1. for interoperability */

4607     private static final long serialVersionUID = -8287574255936472291L;
4608 
4609     /**
4610      * Serializable fields for BigInteger.
4611      *
4612      * @serialField signum  int
4613      *              signum of this BigInteger
4614      * @serialField magnitude byte[]
4615      *              magnitude array of this BigInteger
4616      * @serialField bitCount  int
4617      *              appears in the serialized form for backward compatibility
4618      * @serialField bitLength int
4619      *              appears in the serialized form for backward compatibility
4620      * @serialField firstNonzeroByteNum int
4621      *              appears in the serialized form for backward compatibility
4622      * @serialField lowestSetBit int
4623      *              appears in the serialized form for backward compatibility
4624      */

4625     private static final ObjectStreamField[] serialPersistentFields = {
4626         new ObjectStreamField("signum", Integer.TYPE),
4627         new ObjectStreamField("magnitude", byte[].class),
4628         new ObjectStreamField("bitCount", Integer.TYPE),
4629         new ObjectStreamField("bitLength", Integer.TYPE),
4630         new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE),
4631         new ObjectStreamField("lowestSetBit", Integer.TYPE)
4632         };
4633 
4634     /**
4635      * Reconstitute the {@code BigInteger} instance from a stream (that is,
4636      * deserialize it). The magnitude is read in as an array of bytes
4637      * for historical reasons, but it is converted to an array of ints
4638      * and the byte array is discarded.
4639      * Note:
4640      * The current convention is to initialize the cache fields, bitCountPlusOne,
4641      * bitLengthPlusOne and lowestSetBitPlusTwo, to 0 rather than some other
4642      * marker value. Therefore, no explicit action to set these fields needs to
4643      * be taken in readObject because those fields already have a 0 value by
4644      * default since defaultReadObject is not being used.
4645      */

4646     private void readObject(java.io.ObjectInputStream s)
4647         throws java.io.IOException, ClassNotFoundException {
4648         // prepare to read the alternate persistent fields
4649         ObjectInputStream.GetField fields = s.readFields();
4650 
4651         // Read the alternate persistent fields that we care about
4652         int sign = fields.get("signum", -2);
4653         byte[] magnitude = (byte[])fields.get("magnitude", null);
4654 
4655         // Validate signum
4656         if (sign < -1 || sign > 1) {
4657             String message = "BigInteger: Invalid signum value";
4658             if (fields.defaulted("signum"))
4659                 message = "BigInteger: Signum not present in stream";
4660             throw new java.io.StreamCorruptedException(message);
4661         }
4662         int[] mag = stripLeadingZeroBytes(magnitude, 0, magnitude.length);
4663         if ((mag.length == 0) != (sign == 0)) {
4664             String message = "BigInteger: signum-magnitude mismatch";
4665             if (fields.defaulted("magnitude"))


4692 
4693         static void putSign(BigInteger bi, int sign) {
4694             unsafe.putInt(bi, signumOffset, sign);
4695         }
4696 
4697         static void putMag(BigInteger bi, int[] magnitude) {
4698             unsafe.putReference(bi, magOffset, magnitude);
4699         }
4700     }
4701 
4702     /**
4703      * Save the {@code BigInteger} instance to a stream.  The magnitude of a
4704      * {@code BigInteger} is serialized as a byte array for historical reasons.
4705      * To maintain compatibility with older implementations, the integers
4706      * -1, -1, -2, and -2 are written as the values of the obsolete fields
4707      * {@code bitCount}, {@code bitLength}, {@code lowestSetBit}, and
4708      * {@code firstNonzeroByteNum}, respectively.  These values are compatible
4709      * with older implementations, but will be ignored by current
4710      * implementations.
4711      */

4712     private void writeObject(ObjectOutputStream s) throws IOException {
4713         // set the values of the Serializable fields
4714         ObjectOutputStream.PutField fields = s.putFields();
4715         fields.put("signum", signum);
4716         fields.put("magnitude", magSerializedForm());
4717         // The values written for cached fields are compatible with older
4718         // versions, but are ignored in readObject so don't otherwise matter.
4719         fields.put("bitCount", -1);
4720         fields.put("bitLength", -1);
4721         fields.put("lowestSetBit", -2);
4722         fields.put("firstNonzeroByteNum", -2);
4723 
4724         // save them
4725         s.writeFields();
4726     }
4727 
4728     /**
4729      * Returns the mag array as an array of bytes.
4730      */
4731     private byte[] magSerializedForm() {




4587     * least significant). If the magnitude is zero, return value is undefined.
4588     *
4589     * <p>Note: never used for a BigInteger with a magnitude of zero.
4590     * @see #getInt.
4591     */
4592     private int firstNonzeroIntNum() {
4593         int fn = firstNonzeroIntNumPlusTwo - 2;
4594         if (fn == -2) { // firstNonzeroIntNum not initialized yet
4595             // Search for the first nonzero int
4596             int i;
4597             int mlen = mag.length;
4598             for (i = mlen - 1; i >= 0 && mag[i] == 0; i--)
4599                 ;
4600             fn = mlen - i - 1;
4601             firstNonzeroIntNumPlusTwo = fn + 2; // offset by two to initialize
4602         }
4603         return fn;
4604     }
4605 
4606     /** use serialVersionUID from JDK 1.1. for interoperability */
4607     @java.io.Serial
4608     private static final long serialVersionUID = -8287574255936472291L;
4609 
4610     /**
4611      * Serializable fields for BigInteger.
4612      *
4613      * @serialField signum  int
4614      *              signum of this BigInteger
4615      * @serialField magnitude byte[]
4616      *              magnitude array of this BigInteger
4617      * @serialField bitCount  int
4618      *              appears in the serialized form for backward compatibility
4619      * @serialField bitLength int
4620      *              appears in the serialized form for backward compatibility
4621      * @serialField firstNonzeroByteNum int
4622      *              appears in the serialized form for backward compatibility
4623      * @serialField lowestSetBit int
4624      *              appears in the serialized form for backward compatibility
4625      */
4626     @java.io.Serial
4627     private static final ObjectStreamField[] serialPersistentFields = {
4628         new ObjectStreamField("signum", Integer.TYPE),
4629         new ObjectStreamField("magnitude", byte[].class),
4630         new ObjectStreamField("bitCount", Integer.TYPE),
4631         new ObjectStreamField("bitLength", Integer.TYPE),
4632         new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE),
4633         new ObjectStreamField("lowestSetBit", Integer.TYPE)
4634         };
4635 
4636     /**
4637      * Reconstitute the {@code BigInteger} instance from a stream (that is,
4638      * deserialize it). The magnitude is read in as an array of bytes
4639      * for historical reasons, but it is converted to an array of ints
4640      * and the byte array is discarded.
4641      * Note:
4642      * The current convention is to initialize the cache fields, bitCountPlusOne,
4643      * bitLengthPlusOne and lowestSetBitPlusTwo, to 0 rather than some other
4644      * marker value. Therefore, no explicit action to set these fields needs to
4645      * be taken in readObject because those fields already have a 0 value by
4646      * default since defaultReadObject is not being used.
4647      */
4648     @java.io.Serial
4649     private void readObject(java.io.ObjectInputStream s)
4650         throws java.io.IOException, ClassNotFoundException {
4651         // prepare to read the alternate persistent fields
4652         ObjectInputStream.GetField fields = s.readFields();
4653 
4654         // Read the alternate persistent fields that we care about
4655         int sign = fields.get("signum", -2);
4656         byte[] magnitude = (byte[])fields.get("magnitude", null);
4657 
4658         // Validate signum
4659         if (sign < -1 || sign > 1) {
4660             String message = "BigInteger: Invalid signum value";
4661             if (fields.defaulted("signum"))
4662                 message = "BigInteger: Signum not present in stream";
4663             throw new java.io.StreamCorruptedException(message);
4664         }
4665         int[] mag = stripLeadingZeroBytes(magnitude, 0, magnitude.length);
4666         if ((mag.length == 0) != (sign == 0)) {
4667             String message = "BigInteger: signum-magnitude mismatch";
4668             if (fields.defaulted("magnitude"))


4695 
4696         static void putSign(BigInteger bi, int sign) {
4697             unsafe.putInt(bi, signumOffset, sign);
4698         }
4699 
4700         static void putMag(BigInteger bi, int[] magnitude) {
4701             unsafe.putReference(bi, magOffset, magnitude);
4702         }
4703     }
4704 
4705     /**
4706      * Save the {@code BigInteger} instance to a stream.  The magnitude of a
4707      * {@code BigInteger} is serialized as a byte array for historical reasons.
4708      * To maintain compatibility with older implementations, the integers
4709      * -1, -1, -2, and -2 are written as the values of the obsolete fields
4710      * {@code bitCount}, {@code bitLength}, {@code lowestSetBit}, and
4711      * {@code firstNonzeroByteNum}, respectively.  These values are compatible
4712      * with older implementations, but will be ignored by current
4713      * implementations.
4714      */
4715     @java.io.Serial
4716     private void writeObject(ObjectOutputStream s) throws IOException {
4717         // set the values of the Serializable fields
4718         ObjectOutputStream.PutField fields = s.putFields();
4719         fields.put("signum", signum);
4720         fields.put("magnitude", magSerializedForm());
4721         // The values written for cached fields are compatible with older
4722         // versions, but are ignored in readObject so don't otherwise matter.
4723         fields.put("bitCount", -1);
4724         fields.put("bitLength", -1);
4725         fields.put("lowestSetBit", -2);
4726         fields.put("firstNonzeroByteNum", -2);
4727 
4728         // save them
4729         s.writeFields();
4730     }
4731 
4732     /**
4733      * Returns the mag array as an array of bytes.
4734      */
4735     private byte[] magSerializedForm() {


< prev index next >