< prev index next >

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

Print this page




 263     /**
 264      * Sentinel value for {@link #intCompact} indicating the
 265      * significand information is only available from {@code intVal}.
 266      */
 267     static final long INFLATED = Long.MIN_VALUE;
 268 
 269     private static final BigInteger INFLATED_BIGINT = BigInteger.valueOf(INFLATED);
 270 
 271     /**
 272      * If the absolute value of the significand of this BigDecimal is
 273      * less than or equal to {@code Long.MAX_VALUE}, the value can be
 274      * compactly stored in this field and used in computations.
 275      */
 276     private final transient long intCompact;
 277 
 278     // All 18-digit base ten strings fit into a long; not all 19-digit
 279     // strings will
 280     private static final int MAX_COMPACT_DIGITS = 18;
 281 
 282     /* Appease the serialization gods */

 283     private static final long serialVersionUID = 6108874887143696463L;
 284 
 285     private static final ThreadLocal<StringBuilderHelper>
 286         threadLocalStringBuilderHelper = new ThreadLocal<StringBuilderHelper>() {
 287         @Override
 288         protected StringBuilderHelper initialValue() {
 289             return new StringBuilderHelper();
 290         }
 291     };
 292 
 293     // Cache of common small BigDecimal values.
 294     private static final BigDecimal ZERO_THROUGH_TEN[] = {
 295         new BigDecimal(BigInteger.ZERO,       0,  0, 1),
 296         new BigDecimal(BigInteger.ONE,        1,  0, 1),
 297         new BigDecimal(BigInteger.TWO,        2,  0, 1),
 298         new BigDecimal(BigInteger.valueOf(3), 3,  0, 1),
 299         new BigDecimal(BigInteger.valueOf(4), 4,  0, 1),
 300         new BigDecimal(BigInteger.valueOf(5), 5,  0, 1),
 301         new BigDecimal(BigInteger.valueOf(6), 6,  0, 1),
 302         new BigDecimal(BigInteger.valueOf(7), 7,  0, 1),


4110         private static final long intCompactOffset
4111                 = unsafe.objectFieldOffset(BigDecimal.class, "intCompact");
4112         private static final long intValOffset
4113                 = unsafe.objectFieldOffset(BigDecimal.class, "intVal");
4114 
4115         static void setIntCompact(BigDecimal bd, long val) {
4116             unsafe.putLong(bd, intCompactOffset, val);
4117         }
4118 
4119         static void setIntValVolatile(BigDecimal bd, BigInteger val) {
4120             unsafe.putReferenceVolatile(bd, intValOffset, val);
4121         }
4122     }
4123 
4124     /**
4125      * Reconstitute the {@code BigDecimal} instance from a stream (that is,
4126      * deserialize it).
4127      *
4128      * @param s the stream being read.
4129      */

4130     private void readObject(java.io.ObjectInputStream s)
4131         throws java.io.IOException, ClassNotFoundException {
4132         // Read in all fields
4133         s.defaultReadObject();
4134         // validate possibly bad fields
4135         if (intVal == null) {
4136             String message = "BigDecimal: null intVal in stream";
4137             throw new java.io.StreamCorruptedException(message);
4138         // [all values of scale are now allowed]
4139         }
4140         UnsafeHolder.setIntCompact(this, compactValFor(intVal));
4141     }
4142 
4143    /**
4144     * Serialize this {@code BigDecimal} to the stream in question
4145     *
4146     * @param s the stream to serialize to.
4147     */

4148    private void writeObject(java.io.ObjectOutputStream s)
4149        throws java.io.IOException {
4150        // Must inflate to maintain compatible serial form.
4151        if (this.intVal == null)
4152            UnsafeHolder.setIntValVolatile(this, BigInteger.valueOf(this.intCompact));
4153        // Could reset intVal back to null if it has to be set.
4154        s.defaultWriteObject();
4155    }
4156 
4157     /**
4158      * Returns the length of the absolute value of a {@code long}, in decimal
4159      * digits.
4160      *
4161      * @param x the {@code long}
4162      * @return the length of the unscaled value, in deciaml digits.
4163      */
4164     static int longDigitLength(long x) {
4165         /*
4166          * As described in "Bit Twiddling Hacks" by Sean Anderson,
4167          * (http://graphics.stanford.edu/~seander/bithacks.html)




 263     /**
 264      * Sentinel value for {@link #intCompact} indicating the
 265      * significand information is only available from {@code intVal}.
 266      */
 267     static final long INFLATED = Long.MIN_VALUE;
 268 
 269     private static final BigInteger INFLATED_BIGINT = BigInteger.valueOf(INFLATED);
 270 
 271     /**
 272      * If the absolute value of the significand of this BigDecimal is
 273      * less than or equal to {@code Long.MAX_VALUE}, the value can be
 274      * compactly stored in this field and used in computations.
 275      */
 276     private final transient long intCompact;
 277 
 278     // All 18-digit base ten strings fit into a long; not all 19-digit
 279     // strings will
 280     private static final int MAX_COMPACT_DIGITS = 18;
 281 
 282     /* Appease the serialization gods */
 283     @java.io.Serial
 284     private static final long serialVersionUID = 6108874887143696463L;
 285 
 286     private static final ThreadLocal<StringBuilderHelper>
 287         threadLocalStringBuilderHelper = new ThreadLocal<StringBuilderHelper>() {
 288         @Override
 289         protected StringBuilderHelper initialValue() {
 290             return new StringBuilderHelper();
 291         }
 292     };
 293 
 294     // Cache of common small BigDecimal values.
 295     private static final BigDecimal ZERO_THROUGH_TEN[] = {
 296         new BigDecimal(BigInteger.ZERO,       0,  0, 1),
 297         new BigDecimal(BigInteger.ONE,        1,  0, 1),
 298         new BigDecimal(BigInteger.TWO,        2,  0, 1),
 299         new BigDecimal(BigInteger.valueOf(3), 3,  0, 1),
 300         new BigDecimal(BigInteger.valueOf(4), 4,  0, 1),
 301         new BigDecimal(BigInteger.valueOf(5), 5,  0, 1),
 302         new BigDecimal(BigInteger.valueOf(6), 6,  0, 1),
 303         new BigDecimal(BigInteger.valueOf(7), 7,  0, 1),


4111         private static final long intCompactOffset
4112                 = unsafe.objectFieldOffset(BigDecimal.class, "intCompact");
4113         private static final long intValOffset
4114                 = unsafe.objectFieldOffset(BigDecimal.class, "intVal");
4115 
4116         static void setIntCompact(BigDecimal bd, long val) {
4117             unsafe.putLong(bd, intCompactOffset, val);
4118         }
4119 
4120         static void setIntValVolatile(BigDecimal bd, BigInteger val) {
4121             unsafe.putReferenceVolatile(bd, intValOffset, val);
4122         }
4123     }
4124 
4125     /**
4126      * Reconstitute the {@code BigDecimal} instance from a stream (that is,
4127      * deserialize it).
4128      *
4129      * @param s the stream being read.
4130      */
4131     @java.io.Serial
4132     private void readObject(java.io.ObjectInputStream s)
4133         throws java.io.IOException, ClassNotFoundException {
4134         // Read in all fields
4135         s.defaultReadObject();
4136         // validate possibly bad fields
4137         if (intVal == null) {
4138             String message = "BigDecimal: null intVal in stream";
4139             throw new java.io.StreamCorruptedException(message);
4140         // [all values of scale are now allowed]
4141         }
4142         UnsafeHolder.setIntCompact(this, compactValFor(intVal));
4143     }
4144 
4145    /**
4146     * Serialize this {@code BigDecimal} to the stream in question
4147     *
4148     * @param s the stream to serialize to.
4149     */
4150     @java.io.Serial
4151    private void writeObject(java.io.ObjectOutputStream s)
4152        throws java.io.IOException {
4153        // Must inflate to maintain compatible serial form.
4154        if (this.intVal == null)
4155            UnsafeHolder.setIntValVolatile(this, BigInteger.valueOf(this.intCompact));
4156        // Could reset intVal back to null if it has to be set.
4157        s.defaultWriteObject();
4158    }
4159 
4160     /**
4161      * Returns the length of the absolute value of a {@code long}, in decimal
4162      * digits.
4163      *
4164      * @param x the {@code long}
4165      * @return the length of the unscaled value, in deciaml digits.
4166      */
4167     static int longDigitLength(long x) {
4168         /*
4169          * As described in "Bit Twiddling Hacks" by Sean Anderson,
4170          * (http://graphics.stanford.edu/~seander/bithacks.html)


< prev index next >