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)
|