3699 * 3700 * <p>If the scales of val[0] and val[1] differ, rescale 3701 * (non-destructively) the lower-scaled {@code BigDecimal} so 3702 * they match. That is, the lower-scaled reference will be 3703 * replaced by a reference to a new object with the same scale as 3704 * the other {@code BigDecimal}. 3705 * 3706 * @param val array of two elements referring to the two 3707 * {@code BigDecimal}s to be aligned. 3708 */ 3709 private static void matchScale(BigDecimal[] val) { 3710 if (val[0].scale == val[1].scale) { 3711 return; 3712 } else if (val[0].scale < val[1].scale) { 3713 val[0] = val[0].setScale(val[1].scale, ROUND_UNNECESSARY); 3714 } else if (val[1].scale < val[0].scale) { 3715 val[1] = val[1].setScale(val[0].scale, ROUND_UNNECESSARY); 3716 } 3717 } 3718 3719 private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe(); 3720 private static final long intCompactOffset; 3721 private static final long intValOffset; 3722 static { 3723 try { 3724 intCompactOffset = unsafe.objectFieldOffset 3725 (BigDecimal.class.getDeclaredField("intCompact")); 3726 intValOffset = unsafe.objectFieldOffset 3727 (BigDecimal.class.getDeclaredField("intVal")); 3728 } catch (Exception ex) { 3729 throw new Error(ex); 3730 } 3731 } 3732 3733 private void setIntCompactVolatile(long val) { 3734 unsafe.putLongVolatile(this, intCompactOffset, val); 3735 } 3736 3737 private void setIntValVolatile(BigInteger val) { 3738 unsafe.putObjectVolatile(this, intValOffset, val); 3739 } 3740 3741 /** 3742 * Reconstitute the {@code BigDecimal} instance from a stream (that is, 3743 * deserialize it). 3744 * 3745 * @param s the stream being read. 3746 */ 3747 private void readObject(java.io.ObjectInputStream s) 3748 throws java.io.IOException, ClassNotFoundException { 3749 // Read in all fields 3750 s.defaultReadObject(); 3751 // validate possibly bad fields 3752 if (intVal == null) { 3753 String message = "BigDecimal: null intVal in stream"; 3754 throw new java.io.StreamCorruptedException(message); 3755 // [all values of scale are now allowed] 3756 } 3757 setIntCompactVolatile(compactValFor(intVal)); 3758 } 3759 3760 /** 3761 * Serialize this {@code BigDecimal} to the stream in question 3762 * 3763 * @param s the stream to serialize to. 3764 */ 3765 private void writeObject(java.io.ObjectOutputStream s) 3766 throws java.io.IOException { 3767 // Must inflate to maintain compatible serial form. 3768 if (this.intVal == null) 3769 this.setIntValVolatile(BigInteger.valueOf(this.intCompact)); 3770 // Could reset intVal back to null if it has to be set. 3771 s.defaultWriteObject(); 3772 } 3773 3774 /** 3775 * Returns the length of the absolute value of a {@code long}, in decimal 3776 * digits. 3777 * 3778 * @param x the {@code long} 3779 * @return the length of the unscaled value, in deciaml digits. 3780 */ 3781 static int longDigitLength(long x) { 3782 /* 3783 * As described in "Bit Twiddling Hacks" by Sean Anderson, 3784 * (http://graphics.stanford.edu/~seander/bithacks.html) 3785 * integer log 10 of x is within 1 of (1233/4096)* (1 + 3786 * integer log 2 of x). The fraction 1233/4096 approximates 3787 * log10(2). So we first do a version of log2 (a variant of 3788 * Long class with pre-checks and opposite directionality) and 3789 * then scale and check against powers table. This is a little | 3699 * 3700 * <p>If the scales of val[0] and val[1] differ, rescale 3701 * (non-destructively) the lower-scaled {@code BigDecimal} so 3702 * they match. That is, the lower-scaled reference will be 3703 * replaced by a reference to a new object with the same scale as 3704 * the other {@code BigDecimal}. 3705 * 3706 * @param val array of two elements referring to the two 3707 * {@code BigDecimal}s to be aligned. 3708 */ 3709 private static void matchScale(BigDecimal[] val) { 3710 if (val[0].scale == val[1].scale) { 3711 return; 3712 } else if (val[0].scale < val[1].scale) { 3713 val[0] = val[0].setScale(val[1].scale, ROUND_UNNECESSARY); 3714 } else if (val[1].scale < val[0].scale) { 3715 val[1] = val[1].setScale(val[0].scale, ROUND_UNNECESSARY); 3716 } 3717 } 3718 3719 private static class UnsafeHolder { 3720 private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe(); 3721 private static final long intCompactOffset; 3722 private static final long intValOffset; 3723 static { 3724 try { 3725 intCompactOffset = unsafe.objectFieldOffset 3726 (BigDecimal.class.getDeclaredField("intCompact")); 3727 intValOffset = unsafe.objectFieldOffset 3728 (BigDecimal.class.getDeclaredField("intVal")); 3729 } catch (Exception ex) { 3730 throw new Error(ex); 3731 } 3732 } 3733 private static void setIntCompactVolatile(BigDecimal bd, long val) { 3734 unsafe.putLongVolatile(bd, intCompactOffset, val); 3735 } 3736 3737 private static void setIntValVolatile(BigDecimal bd, BigInteger val) { 3738 unsafe.putObjectVolatile(bd, intValOffset, val); 3739 } 3740 } 3741 3742 /** 3743 * Reconstitute the {@code BigDecimal} instance from a stream (that is, 3744 * deserialize it). 3745 * 3746 * @param s the stream being read. 3747 */ 3748 private void readObject(java.io.ObjectInputStream s) 3749 throws java.io.IOException, ClassNotFoundException { 3750 // Read in all fields 3751 s.defaultReadObject(); 3752 // validate possibly bad fields 3753 if (intVal == null) { 3754 String message = "BigDecimal: null intVal in stream"; 3755 throw new java.io.StreamCorruptedException(message); 3756 // [all values of scale are now allowed] 3757 } 3758 UnsafeHolder.setIntCompactVolatile(this, compactValFor(intVal)); 3759 } 3760 3761 /** 3762 * Serialize this {@code BigDecimal} to the stream in question 3763 * 3764 * @param s the stream to serialize to. 3765 */ 3766 private void writeObject(java.io.ObjectOutputStream s) 3767 throws java.io.IOException { 3768 // Must inflate to maintain compatible serial form. 3769 if (this.intVal == null) 3770 UnsafeHolder.setIntValVolatile(this, BigInteger.valueOf(this.intCompact)); 3771 // Could reset intVal back to null if it has to be set. 3772 s.defaultWriteObject(); 3773 } 3774 3775 /** 3776 * Returns the length of the absolute value of a {@code long}, in decimal 3777 * digits. 3778 * 3779 * @param x the {@code long} 3780 * @return the length of the unscaled value, in deciaml digits. 3781 */ 3782 static int longDigitLength(long x) { 3783 /* 3784 * As described in "Bit Twiddling Hacks" by Sean Anderson, 3785 * (http://graphics.stanford.edu/~seander/bithacks.html) 3786 * integer log 10 of x is within 1 of (1233/4096)* (1 + 3787 * integer log 2 of x). The fraction 1233/4096 approximates 3788 * log10(2). So we first do a version of log2 (a variant of 3789 * Long class with pre-checks and opposite directionality) and 3790 * then scale and check against powers table. This is a little |