| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package java.math; |
| |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.io.Serializable; |
| import java.util.Arrays; |
| import libcore.math.MathUtils; |
| |
| /** |
| * An immutable arbitrary-precision signed decimal. |
| * |
| * <p>A value is represented by an arbitrary-precision "unscaled value" and a signed 32-bit "scale", |
| * combined thus: {@code unscaled * 10<sup>-scale</sup>}. See {@link #unscaledValue} and {@link #scale}. |
| * |
| * <p>Most operations allow you to supply a {@link MathContext} to specify a desired rounding mode. |
| */ |
| public class BigDecimal extends Number implements Comparable<BigDecimal>, Serializable { |
| |
| /** |
| * Rounding mode where positive values are rounded towards positive infinity |
| * and negative values towards negative infinity. |
| * |
| * @see RoundingMode#UP |
| */ |
| public static final int ROUND_UP = 0; |
| |
| /** |
| * Rounding mode where the values are rounded towards zero. |
| * |
| * @see RoundingMode#DOWN |
| */ |
| public static final int ROUND_DOWN = 1; |
| |
| /** |
| * Rounding mode to round towards positive infinity. For positive values |
| * this rounding mode behaves as {@link #ROUND_UP}, for negative values as |
| * {@link #ROUND_DOWN}. |
| * |
| * @see RoundingMode#CEILING |
| */ |
| public static final int ROUND_CEILING = 2; |
| |
| /** |
| * Rounding mode to round towards negative infinity. For positive values |
| * this rounding mode behaves as {@link #ROUND_DOWN}, for negative values as |
| * {@link #ROUND_UP}. |
| * |
| * @see RoundingMode#FLOOR |
| */ |
| public static final int ROUND_FLOOR = 3; |
| |
| /** |
| * Rounding mode where values are rounded towards the nearest neighbor. |
| * Ties are broken by rounding up. |
| * |
| * @see RoundingMode#HALF_UP |
| */ |
| public static final int ROUND_HALF_UP = 4; |
| |
| /** |
| * Rounding mode where values are rounded towards the nearest neighbor. |
| * Ties are broken by rounding down. |
| * |
| * @see RoundingMode#HALF_DOWN |
| */ |
| public static final int ROUND_HALF_DOWN = 5; |
| |
| /** |
| * Rounding mode where values are rounded towards the nearest neighbor. |
| * Ties are broken by rounding to the even neighbor. |
| * |
| * @see RoundingMode#HALF_EVEN |
| */ |
| public static final int ROUND_HALF_EVEN = 6; |
| |
| /** |
| * Rounding mode where the rounding operations throws an {@code |
| * ArithmeticException} for the case that rounding is necessary, i.e. for |
| * the case that the value cannot be represented exactly. |
| * |
| * @see RoundingMode#UNNECESSARY |
| */ |
| public static final int ROUND_UNNECESSARY = 7; |
| |
| /** This is the serialVersionUID used by the sun implementation. */ |
| private static final long serialVersionUID = 6108874887143696463L; |
| |
| /** The double closest to {@code Log10(2)}. */ |
| private static final double LOG10_2 = 0.3010299956639812; |
| |
| /** The <code>String</code> representation is cached. */ |
| private transient String toStringImage = null; |
| |
| /** Cache for the hash code. */ |
| private transient int hashCode = 0; |
| |
| /** |
| * An array with powers of five that fit in the type <code>long</code> |
| * (<code>5^0,5^1,...,5^27</code>). |
| */ |
| private static final BigInteger[] FIVE_POW; |
| |
| /** |
| * An array with powers of ten that fit in the type <code>long</code> |
| * (<code>10^0,10^1,...,10^18</code>). |
| */ |
| private static final BigInteger[] TEN_POW; |
| |
| private static final long[] LONG_FIVE_POW = new long[] |
| { 1L, |
| 5L, |
| 25L, |
| 125L, |
| 625L, |
| 3125L, |
| 15625L, |
| 78125L, |
| 390625L, |
| 1953125L, |
| 9765625L, |
| 48828125L, |
| 244140625L, |
| 1220703125L, |
| 6103515625L, |
| 30517578125L, |
| 152587890625L, |
| 762939453125L, |
| 3814697265625L, |
| 19073486328125L, |
| 95367431640625L, |
| 476837158203125L, |
| 2384185791015625L, |
| 11920928955078125L, |
| 59604644775390625L, |
| 298023223876953125L, |
| 1490116119384765625L, |
| 7450580596923828125L, }; |
| |
| private static final int[] LONG_FIVE_POW_BIT_LENGTH = new int[LONG_FIVE_POW.length]; |
| private static final int[] LONG_POWERS_OF_TEN_BIT_LENGTH = new int[MathUtils.LONG_POWERS_OF_TEN.length]; |
| |
| private static final int BI_SCALED_BY_ZERO_LENGTH = 11; |
| |
| /** |
| * An array with the first <code>BigInteger</code> scaled by zero. |
| * (<code>[0,0],[1,0],...,[10,0]</code>). |
| */ |
| private static final BigDecimal[] BI_SCALED_BY_ZERO = new BigDecimal[BI_SCALED_BY_ZERO_LENGTH]; |
| |
| /** |
| * An array with the zero number scaled by the first positive scales. |
| * (<code>0*10^0, 0*10^1, ..., 0*10^10</code>). |
| */ |
| private static final BigDecimal[] ZERO_SCALED_BY = new BigDecimal[11]; |
| |
| /** An array filled with characters <code>'0'</code>. */ |
| private static final char[] CH_ZEROS = new char[100]; |
| |
| static { |
| Arrays.fill(CH_ZEROS, '0'); |
| |
| for (int i = 0; i < ZERO_SCALED_BY.length; ++i) { |
| BI_SCALED_BY_ZERO[i] = new BigDecimal(i, 0); |
| ZERO_SCALED_BY[i] = new BigDecimal(0, i); |
| } |
| for (int i = 0; i < LONG_FIVE_POW_BIT_LENGTH.length; ++i) { |
| LONG_FIVE_POW_BIT_LENGTH[i] = bitLength(LONG_FIVE_POW[i]); |
| } |
| for (int i = 0; i < LONG_POWERS_OF_TEN_BIT_LENGTH.length; ++i) { |
| LONG_POWERS_OF_TEN_BIT_LENGTH[i] = bitLength(MathUtils.LONG_POWERS_OF_TEN[i]); |
| } |
| |
| // Taking the references of useful powers. |
| TEN_POW = Multiplication.bigTenPows; |
| FIVE_POW = Multiplication.bigFivePows; |
| } |
| |
| /** |
| * The constant zero as a {@code BigDecimal}. |
| */ |
| public static final BigDecimal ZERO = new BigDecimal(0, 0); |
| |
| /** |
| * The constant one as a {@code BigDecimal}. |
| */ |
| public static final BigDecimal ONE = new BigDecimal(1, 0); |
| |
| /** |
| * The constant ten as a {@code BigDecimal}. |
| */ |
| public static final BigDecimal TEN = new BigDecimal(10, 0); |
| |
| /** |
| * The arbitrary precision integer (unscaled value) in the internal |
| * representation of {@code BigDecimal}. |
| */ |
| private BigInteger intVal; |
| |
| private transient int bitLength; |
| |
| private transient long smallValue; |
| |
| /** |
| * The 32-bit integer scale in the internal representation of {@code BigDecimal}. |
| */ |
| private int scale; |
| |
| /** |
| * Represent the number of decimal digits in the unscaled value. This |
| * precision is calculated the first time, and used in the following calls |
| * of method <code>precision()</code>. Note that some call to the private |
| * method <code>inplaceRound()</code> could update this field. |
| * |
| * @see #precision() |
| * @see #inplaceRound(MathContext) |
| */ |
| private transient int precision = 0; |
| |
| private BigDecimal(long smallValue, int scale){ |
| this.smallValue = smallValue; |
| this.scale = scale; |
| this.bitLength = bitLength(smallValue); |
| } |
| |
| private BigDecimal(int smallValue, int scale){ |
| this.smallValue = smallValue; |
| this.scale = scale; |
| this.bitLength = bitLength(smallValue); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from a string representation |
| * given as a character array. |
| * |
| * @param in |
| * array of characters containing the string representation of |
| * this {@code BigDecimal}. |
| * @param offset |
| * first index to be copied. |
| * @param len |
| * number of characters to be used. |
| * @throws NumberFormatException |
| * if {@code offset < 0 || len <= 0 || offset+len-1 < 0 || |
| * offset+len-1 >= in.length}, or if {@code in} does not |
| * contain a valid string representation of a big decimal. |
| */ |
| public BigDecimal(char[] in, int offset, int len) { |
| int begin = offset; // first index to be copied |
| int last = offset + (len - 1); // last index to be copied |
| String scaleString; // buffer for scale |
| StringBuilder unscaledBuffer; // buffer for unscaled value |
| long newScale; // the new scale |
| |
| if (in == null) { |
| throw new NullPointerException("in == null"); |
| } |
| if ((last >= in.length) || (offset < 0) || (len <= 0) || (last < 0)) { |
| throw new NumberFormatException("Bad offset/length: offset=" + offset + |
| " len=" + len + " in.length=" + in.length); |
| } |
| unscaledBuffer = new StringBuilder(len); |
| int bufLength = 0; |
| // To skip a possible '+' symbol |
| if ((offset <= last) && (in[offset] == '+')) { |
| offset++; |
| begin++; |
| } |
| int counter = 0; |
| boolean wasNonZero = false; |
| // Accumulating all digits until a possible decimal point |
| for (; (offset <= last) && (in[offset] != '.') && (in[offset] != 'e') && (in[offset] != 'E'); offset++) { |
| if (!wasNonZero) { |
| if (in[offset] == '0') { |
| counter++; |
| } else { |
| wasNonZero = true; |
| } |
| } |
| |
| } |
| unscaledBuffer.append(in, begin, offset - begin); |
| bufLength += offset - begin; |
| // A decimal point was found |
| if ((offset <= last) && (in[offset] == '.')) { |
| offset++; |
| // Accumulating all digits until a possible exponent |
| begin = offset; |
| for (; (offset <= last) && (in[offset] != 'e') |
| && (in[offset] != 'E'); offset++) { |
| if (!wasNonZero) { |
| if (in[offset] == '0') { |
| counter++; |
| } else { |
| wasNonZero = true; |
| } |
| } |
| } |
| scale = offset - begin; |
| bufLength +=scale; |
| unscaledBuffer.append(in, begin, scale); |
| } else { |
| scale = 0; |
| } |
| // An exponent was found |
| if ((offset <= last) && ((in[offset] == 'e') || (in[offset] == 'E'))) { |
| offset++; |
| // Checking for a possible sign of scale |
| begin = offset; |
| if ((offset <= last) && (in[offset] == '+')) { |
| offset++; |
| if ((offset <= last) && (in[offset] != '-')) { |
| begin++; |
| } |
| } |
| // Accumulating all remaining digits |
| scaleString = String.valueOf(in, begin, last + 1 - begin); |
| // Checking if the scale is defined |
| newScale = (long)scale - Integer.parseInt(scaleString); |
| scale = (int)newScale; |
| if (newScale != scale) { |
| throw new NumberFormatException("Scale out of range"); |
| } |
| } |
| // Parsing the unscaled value |
| if (bufLength < 19) { |
| smallValue = Long.parseLong(unscaledBuffer.toString()); |
| bitLength = bitLength(smallValue); |
| } else { |
| setUnscaledValue(new BigInteger(unscaledBuffer.toString())); |
| } |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from a string representation |
| * given as a character array. |
| * |
| * @param in |
| * array of characters containing the string representation of |
| * this {@code BigDecimal}. |
| * @param offset |
| * first index to be copied. |
| * @param len |
| * number of characters to be used. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws NumberFormatException |
| * if {@code offset < 0 || len <= 0 || offset+len-1 < 0 || |
| * offset+len-1 >= in.length}, or if {@code in} does not |
| * contain a valid string representation of a big decimal. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code mc.roundingMode == |
| * UNNECESSARY} and the new big decimal cannot be represented |
| * within the given precision without rounding. |
| */ |
| public BigDecimal(char[] in, int offset, int len, MathContext mc) { |
| this(in, offset, len); |
| inplaceRound(mc); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from a string representation |
| * given as a character array. |
| * |
| * @param in |
| * array of characters containing the string representation of |
| * this {@code BigDecimal}. |
| * @throws NumberFormatException |
| * if {@code in} does not contain a valid string representation |
| * of a big decimal. |
| */ |
| public BigDecimal(char[] in) { |
| this(in, 0, in.length); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from a string representation |
| * given as a character array. The result is rounded according to the |
| * specified math context. |
| * |
| * @param in |
| * array of characters containing the string representation of |
| * this {@code BigDecimal}. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws NumberFormatException |
| * if {@code in} does not contain a valid string representation |
| * of a big decimal. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code mc.roundingMode == |
| * UNNECESSARY} and the new big decimal cannot be represented |
| * within the given precision without rounding. |
| */ |
| public BigDecimal(char[] in, MathContext mc) { |
| this(in, 0, in.length); |
| inplaceRound(mc); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from a string |
| * representation. |
| * |
| * @throws NumberFormatException |
| * if {@code val} does not contain a valid string representation |
| * of a big decimal. |
| */ |
| public BigDecimal(String val) { |
| this(val.toCharArray(), 0, val.length()); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from a string |
| * representation. The result is rounded according to the specified math |
| * context. |
| * |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws NumberFormatException |
| * if {@code val} does not contain a valid string representation |
| * of a big decimal. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code mc.roundingMode == |
| * UNNECESSARY} and the new big decimal cannot be represented |
| * within the given precision without rounding. |
| */ |
| public BigDecimal(String val, MathContext mc) { |
| this(val.toCharArray(), 0, val.length()); |
| inplaceRound(mc); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from the 64bit double |
| * {@code val}. The constructed big decimal is equivalent to the given |
| * double. For example, {@code new BigDecimal(0.1)} is equal to {@code |
| * 0.1000000000000000055511151231257827021181583404541015625}. This happens |
| * as {@code 0.1} cannot be represented exactly in binary. |
| * <p> |
| * To generate a big decimal instance which is equivalent to {@code 0.1} use |
| * the {@code BigDecimal(String)} constructor. |
| * |
| * @param val |
| * double value to be converted to a {@code BigDecimal} instance. |
| * @throws NumberFormatException |
| * if {@code val} is infinity or not a number. |
| */ |
| public BigDecimal(double val) { |
| if (Double.isInfinite(val) || Double.isNaN(val)) { |
| throw new NumberFormatException("Infinity or NaN: " + val); |
| } |
| long bits = Double.doubleToLongBits(val); // IEEE-754 |
| long mantissa; |
| int trailingZeros; |
| // Extracting the exponent, note that the bias is 1023 |
| scale = 1075 - (int)((bits >> 52) & 0x7FFL); |
| // Extracting the 52 bits of the mantissa. |
| mantissa = (scale == 1075) ? (bits & 0xFFFFFFFFFFFFFL) << 1 |
| : (bits & 0xFFFFFFFFFFFFFL) | 0x10000000000000L; |
| if (mantissa == 0) { |
| scale = 0; |
| precision = 1; |
| } |
| // To simplify all factors '2' in the mantissa |
| if (scale > 0) { |
| trailingZeros = Math.min(scale, Long.numberOfTrailingZeros(mantissa)); |
| mantissa >>>= trailingZeros; |
| scale -= trailingZeros; |
| } |
| // Calculating the new unscaled value and the new scale |
| if((bits >> 63) != 0) { |
| mantissa = -mantissa; |
| } |
| int mantissaBits = bitLength(mantissa); |
| if (scale < 0) { |
| bitLength = mantissaBits == 0 ? 0 : mantissaBits - scale; |
| if(bitLength < 64) { |
| smallValue = mantissa << (-scale); |
| } else { |
| BigInt bi = new BigInt(); |
| bi.putLongInt(mantissa); |
| bi.shift(-scale); |
| intVal = new BigInteger(bi); |
| } |
| scale = 0; |
| } else if (scale > 0) { |
| // m * 2^e = (m * 5^(-e)) * 10^e |
| if(scale < LONG_FIVE_POW.length |
| && mantissaBits+LONG_FIVE_POW_BIT_LENGTH[scale] < 64) { |
| smallValue = mantissa * LONG_FIVE_POW[scale]; |
| bitLength = bitLength(smallValue); |
| } else { |
| setUnscaledValue(Multiplication.multiplyByFivePow(BigInteger.valueOf(mantissa), scale)); |
| } |
| } else { // scale == 0 |
| smallValue = mantissa; |
| bitLength = mantissaBits; |
| } |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from the 64bit double |
| * {@code val}. The constructed big decimal is equivalent to the given |
| * double. For example, {@code new BigDecimal(0.1)} is equal to {@code |
| * 0.1000000000000000055511151231257827021181583404541015625}. This happens |
| * as {@code 0.1} cannot be represented exactly in binary. |
| * <p> |
| * To generate a big decimal instance which is equivalent to {@code 0.1} use |
| * the {@code BigDecimal(String)} constructor. |
| * |
| * @param val |
| * double value to be converted to a {@code BigDecimal} instance. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws NumberFormatException |
| * if {@code val} is infinity or not a number. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code mc.roundingMode == |
| * UNNECESSARY} and the new big decimal cannot be represented |
| * within the given precision without rounding. |
| */ |
| public BigDecimal(double val, MathContext mc) { |
| this(val); |
| inplaceRound(mc); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from the given big integer |
| * {@code val}. The scale of the result is {@code 0}. |
| */ |
| public BigDecimal(BigInteger val) { |
| this(val, 0); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from the given big integer |
| * {@code val}. The scale of the result is {@code 0}. |
| * |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code mc.roundingMode == |
| * UNNECESSARY} and the new big decimal cannot be represented |
| * within the given precision without rounding. |
| */ |
| public BigDecimal(BigInteger val, MathContext mc) { |
| this(val); |
| inplaceRound(mc); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from a given unscaled value |
| * {@code unscaledVal} and a given scale. The value of this instance is |
| * {@code unscaledVal * 10<sup>-scale</sup>}). |
| * |
| * @throws NullPointerException |
| * if {@code unscaledVal == null}. |
| */ |
| public BigDecimal(BigInteger unscaledVal, int scale) { |
| if (unscaledVal == null) { |
| throw new NullPointerException("unscaledVal == null"); |
| } |
| this.scale = scale; |
| setUnscaledValue(unscaledVal); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from a given unscaled value |
| * {@code unscaledVal} and a given scale. The value of this instance is |
| * {@code unscaledVal * 10<sup>-scale</sup>). The result is rounded according |
| * to the specified math context. |
| * |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code mc.roundingMode == |
| * UNNECESSARY} and the new big decimal cannot be represented |
| * within the given precision without rounding. |
| * @throws NullPointerException |
| * if {@code unscaledVal == null}. |
| */ |
| public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) { |
| this(unscaledVal, scale); |
| inplaceRound(mc); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from the given int |
| * {@code val}. The scale of the result is 0. |
| * |
| * @param val |
| * int value to be converted to a {@code BigDecimal} instance. |
| */ |
| public BigDecimal(int val) { |
| this(val,0); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from the given int {@code |
| * val}. The scale of the result is {@code 0}. The result is rounded |
| * according to the specified math context. |
| * |
| * @param val |
| * int value to be converted to a {@code BigDecimal} instance. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code c.roundingMode == |
| * UNNECESSARY} and the new big decimal cannot be represented |
| * within the given precision without rounding. |
| */ |
| public BigDecimal(int val, MathContext mc) { |
| this(val,0); |
| inplaceRound(mc); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from the given long {@code |
| * val}. The scale of the result is {@code 0}. |
| * |
| * @param val |
| * long value to be converted to a {@code BigDecimal} instance. |
| */ |
| public BigDecimal(long val) { |
| this(val,0); |
| } |
| |
| /** |
| * Constructs a new {@code BigDecimal} instance from the given long {@code |
| * val}. The scale of the result is {@code 0}. The result is rounded |
| * according to the specified math context. |
| * |
| * @param val |
| * long value to be converted to a {@code BigDecimal} instance. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code mc.roundingMode == |
| * UNNECESSARY} and the new big decimal cannot be represented |
| * within the given precision without rounding. |
| */ |
| public BigDecimal(long val, MathContext mc) { |
| this(val); |
| inplaceRound(mc); |
| } |
| |
| /* Public Methods */ |
| |
| /** |
| * Returns a new {@code BigDecimal} instance whose value is equal to {@code |
| * unscaledVal * 10<sup>-scale</sup>}). The scale of the result is {@code |
| * scale}, and its unscaled value is {@code unscaledVal}. |
| */ |
| public static BigDecimal valueOf(long unscaledVal, int scale) { |
| if (scale == 0) { |
| return valueOf(unscaledVal); |
| } |
| if ((unscaledVal == 0) && (scale >= 0) |
| && (scale < ZERO_SCALED_BY.length)) { |
| return ZERO_SCALED_BY[scale]; |
| } |
| return new BigDecimal(unscaledVal, scale); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} instance whose value is equal to {@code |
| * unscaledVal}. The scale of the result is {@code 0}, and its unscaled |
| * value is {@code unscaledVal}. |
| * |
| * @param unscaledVal |
| * value to be converted to a {@code BigDecimal}. |
| * @return {@code BigDecimal} instance with the value {@code unscaledVal}. |
| */ |
| public static BigDecimal valueOf(long unscaledVal) { |
| if ((unscaledVal >= 0) && (unscaledVal < BI_SCALED_BY_ZERO_LENGTH)) { |
| return BI_SCALED_BY_ZERO[(int)unscaledVal]; |
| } |
| return new BigDecimal(unscaledVal,0); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} instance whose value is equal to {@code |
| * val}. The new decimal is constructed as if the {@code BigDecimal(String)} |
| * constructor is called with an argument which is equal to {@code |
| * Double.toString(val)}. For example, {@code valueOf("0.1")} is converted to |
| * (unscaled=1, scale=1), although the double {@code 0.1} cannot be |
| * represented exactly as a double value. In contrast to that, a new {@code |
| * BigDecimal(0.1)} instance has the value {@code |
| * 0.1000000000000000055511151231257827021181583404541015625} with an |
| * unscaled value {@code 1000000000000000055511151231257827021181583404541015625} |
| * and the scale {@code 55}. |
| * |
| * @param val |
| * double value to be converted to a {@code BigDecimal}. |
| * @return {@code BigDecimal} instance with the value {@code val}. |
| * @throws NumberFormatException |
| * if {@code val} is infinite or {@code val} is not a number |
| */ |
| public static BigDecimal valueOf(double val) { |
| if (Double.isInfinite(val) || Double.isNaN(val)) { |
| throw new NumberFormatException("Infinity or NaN: " + val); |
| } |
| return new BigDecimal(Double.toString(val)); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this + augend}. |
| * The scale of the result is the maximum of the scales of the two |
| * arguments. |
| * |
| * @param augend |
| * value to be added to {@code this}. |
| * @return {@code this + augend}. |
| * @throws NullPointerException |
| * if {@code augend == null}. |
| */ |
| public BigDecimal add(BigDecimal augend) { |
| int diffScale = this.scale - augend.scale; |
| // Fast return when some operand is zero |
| if (this.isZero()) { |
| if (diffScale <= 0) { |
| return augend; |
| } |
| if (augend.isZero()) { |
| return this; |
| } |
| } else if (augend.isZero()) { |
| if (diffScale >= 0) { |
| return this; |
| } |
| } |
| // Let be: this = [u1,s1] and augend = [u2,s2] |
| if (diffScale == 0) { |
| // case s1 == s2: [u1 + u2 , s1] |
| if (Math.max(this.bitLength, augend.bitLength) + 1 < 64) { |
| return valueOf(this.smallValue + augend.smallValue, this.scale); |
| } |
| return new BigDecimal(this.getUnscaledValue().add(augend.getUnscaledValue()), this.scale); |
| } else if (diffScale > 0) { |
| // case s1 > s2 : [(u1 + u2) * 10 ^ (s1 - s2) , s1] |
| return addAndMult10(this, augend, diffScale); |
| } else {// case s2 > s1 : [(u2 + u1) * 10 ^ (s2 - s1) , s2] |
| return addAndMult10(augend, this, -diffScale); |
| } |
| } |
| |
| private static BigDecimal addAndMult10(BigDecimal thisValue,BigDecimal augend, int diffScale) { |
| if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length && |
| Math.max(thisValue.bitLength,augend.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale])+1<64) { |
| return valueOf(thisValue.smallValue+augend.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale],thisValue.scale); |
| } else { |
| BigInt bi = Multiplication.multiplyByTenPow(augend.getUnscaledValue(),diffScale).getBigInt(); |
| bi.add(thisValue.getUnscaledValue().getBigInt()); |
| return new BigDecimal(new BigInteger(bi), thisValue.scale); |
| } |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this + augend}. |
| * The result is rounded according to the passed context {@code mc}. |
| * |
| * @param augend |
| * value to be added to {@code this}. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @return {@code this + augend}. |
| * @throws NullPointerException |
| * if {@code augend == null} or {@code mc == null}. |
| */ |
| public BigDecimal add(BigDecimal augend, MathContext mc) { |
| BigDecimal larger; // operand with the largest unscaled value |
| BigDecimal smaller; // operand with the smallest unscaled value |
| BigInteger tempBI; |
| long diffScale = (long)this.scale - augend.scale; |
| int largerSignum; |
| // Some operand is zero or the precision is infinity |
| if ((augend.isZero()) || (this.isZero()) |
| || (mc.getPrecision() == 0)) { |
| return add(augend).round(mc); |
| } |
| // Cases where there is room for optimizations |
| if (this.approxPrecision() < diffScale - 1) { |
| larger = augend; |
| smaller = this; |
| } else if (augend.approxPrecision() < -diffScale - 1) { |
| larger = this; |
| smaller = augend; |
| } else {// No optimization is done |
| return add(augend).round(mc); |
| } |
| if (mc.getPrecision() >= larger.approxPrecision()) { |
| // No optimization is done |
| return add(augend).round(mc); |
| } |
| // Cases where it's unnecessary to add two numbers with very different scales |
| largerSignum = larger.signum(); |
| if (largerSignum == smaller.signum()) { |
| tempBI = Multiplication.multiplyByPositiveInt(larger.getUnscaledValue(),10) |
| .add(BigInteger.valueOf(largerSignum)); |
| } else { |
| tempBI = larger.getUnscaledValue().subtract( |
| BigInteger.valueOf(largerSignum)); |
| tempBI = Multiplication.multiplyByPositiveInt(tempBI,10) |
| .add(BigInteger.valueOf(largerSignum * 9)); |
| } |
| // Rounding the improved adding |
| larger = new BigDecimal(tempBI, larger.scale + 1); |
| return larger.round(mc); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}. |
| * The scale of the result is the maximum of the scales of the two arguments. |
| * |
| * @param subtrahend |
| * value to be subtracted from {@code this}. |
| * @return {@code this - subtrahend}. |
| * @throws NullPointerException |
| * if {@code subtrahend == null}. |
| */ |
| public BigDecimal subtract(BigDecimal subtrahend) { |
| int diffScale = this.scale - subtrahend.scale; |
| // Fast return when some operand is zero |
| if (this.isZero()) { |
| if (diffScale <= 0) { |
| return subtrahend.negate(); |
| } |
| if (subtrahend.isZero()) { |
| return this; |
| } |
| } else if (subtrahend.isZero()) { |
| if (diffScale >= 0) { |
| return this; |
| } |
| } |
| // Let be: this = [u1,s1] and subtrahend = [u2,s2] so: |
| if (diffScale == 0) { |
| // case s1 = s2 : [u1 - u2 , s1] |
| if (Math.max(this.bitLength, subtrahend.bitLength) + 1 < 64) { |
| return valueOf(this.smallValue - subtrahend.smallValue,this.scale); |
| } |
| return new BigDecimal(this.getUnscaledValue().subtract(subtrahend.getUnscaledValue()), this.scale); |
| } else if (diffScale > 0) { |
| // case s1 > s2 : [ u1 - u2 * 10 ^ (s1 - s2) , s1 ] |
| if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length && |
| Math.max(this.bitLength,subtrahend.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale])+1<64) { |
| return valueOf(this.smallValue-subtrahend.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale],this.scale); |
| } |
| return new BigDecimal(this.getUnscaledValue().subtract( |
| Multiplication.multiplyByTenPow(subtrahend.getUnscaledValue(),diffScale)), this.scale); |
| } else {// case s2 > s1 : [ u1 * 10 ^ (s2 - s1) - u2 , s2 ] |
| diffScale = -diffScale; |
| if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length && |
| Math.max(this.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale],subtrahend.bitLength)+1<64) { |
| return valueOf(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale]-subtrahend.smallValue,subtrahend.scale); |
| } |
| return new BigDecimal(Multiplication.multiplyByTenPow(this.getUnscaledValue(),diffScale) |
| .subtract(subtrahend.getUnscaledValue()), subtrahend.scale); |
| } |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}. |
| * The result is rounded according to the passed context {@code mc}. |
| * |
| * @param subtrahend |
| * value to be subtracted from {@code this}. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @return {@code this - subtrahend}. |
| * @throws NullPointerException |
| * if {@code subtrahend == null} or {@code mc == null}. |
| */ |
| public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) { |
| long diffScale = subtrahend.scale - (long)this.scale; |
| int thisSignum; |
| BigDecimal leftOperand; // it will be only the left operand (this) |
| BigInteger tempBI; |
| // Some operand is zero or the precision is infinity |
| if ((subtrahend.isZero()) || (this.isZero()) |
| || (mc.getPrecision() == 0)) { |
| return subtract(subtrahend).round(mc); |
| } |
| // Now: this != 0 and subtrahend != 0 |
| if (subtrahend.approxPrecision() < diffScale - 1) { |
| // Cases where it is unnecessary to subtract two numbers with very different scales |
| if (mc.getPrecision() < this.approxPrecision()) { |
| thisSignum = this.signum(); |
| if (thisSignum != subtrahend.signum()) { |
| tempBI = Multiplication.multiplyByPositiveInt(this.getUnscaledValue(), 10) |
| .add(BigInteger.valueOf(thisSignum)); |
| } else { |
| tempBI = this.getUnscaledValue().subtract(BigInteger.valueOf(thisSignum)); |
| tempBI = Multiplication.multiplyByPositiveInt(tempBI, 10) |
| .add(BigInteger.valueOf(thisSignum * 9)); |
| } |
| // Rounding the improved subtracting |
| leftOperand = new BigDecimal(tempBI, this.scale + 1); |
| return leftOperand.round(mc); |
| } |
| } |
| // No optimization is done |
| return subtract(subtrahend).round(mc); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this * |
| * multiplicand}. The scale of the result is the sum of the scales of the |
| * two arguments. |
| * |
| * @param multiplicand |
| * value to be multiplied with {@code this}. |
| * @return {@code this * multiplicand}. |
| * @throws NullPointerException |
| * if {@code multiplicand == null}. |
| */ |
| public BigDecimal multiply(BigDecimal multiplicand) { |
| long newScale = (long)this.scale + multiplicand.scale; |
| |
| if ((this.isZero()) || (multiplicand.isZero())) { |
| return zeroScaledBy(newScale); |
| } |
| /* Let be: this = [u1,s1] and multiplicand = [u2,s2] so: |
| * this x multiplicand = [ s1 * s2 , s1 + s2 ] */ |
| if (this.bitLength + multiplicand.bitLength < 64) { |
| long unscaledValue = this.smallValue * multiplicand.smallValue; |
| // b/19185440 Case where result should be +2^63 but unscaledValue overflowed to -2^63 |
| boolean longMultiplicationOverflowed = (unscaledValue == Long.MIN_VALUE) && |
| (Math.signum(smallValue) * Math.signum(multiplicand.smallValue) > 0); |
| if (!longMultiplicationOverflowed) { |
| return valueOf(unscaledValue, safeLongToInt(newScale)); |
| } |
| } |
| return new BigDecimal(this.getUnscaledValue().multiply( |
| multiplicand.getUnscaledValue()), safeLongToInt(newScale)); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this * |
| * multiplicand}. The result is rounded according to the passed context |
| * {@code mc}. |
| * |
| * @param multiplicand |
| * value to be multiplied with {@code this}. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @return {@code this * multiplicand}. |
| * @throws NullPointerException |
| * if {@code multiplicand == null} or {@code mc == null}. |
| */ |
| public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) { |
| BigDecimal result = multiply(multiplicand); |
| |
| result.inplaceRound(mc); |
| return result; |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this / divisor}. |
| * As scale of the result the parameter {@code scale} is used. If rounding |
| * is required to meet the specified scale, then the specified rounding mode |
| * {@code roundingMode} is applied. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @param scale |
| * the scale of the result returned. |
| * @param roundingMode |
| * rounding mode to be used to round the result. |
| * @return {@code this / divisor} rounded according to the given rounding |
| * mode. |
| * @throws NullPointerException |
| * if {@code divisor == null}. |
| * @throws IllegalArgumentException |
| * if {@code roundingMode} is not a valid rounding mode. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @throws ArithmeticException |
| * if {@code roundingMode == ROUND_UNNECESSARY} and rounding is |
| * necessary according to the given scale. |
| */ |
| public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) { |
| return divide(divisor, scale, RoundingMode.valueOf(roundingMode)); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this / divisor}. |
| * As scale of the result the parameter {@code scale} is used. If rounding |
| * is required to meet the specified scale, then the specified rounding mode |
| * {@code roundingMode} is applied. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @param scale |
| * the scale of the result returned. |
| * @param roundingMode |
| * rounding mode to be used to round the result. |
| * @return {@code this / divisor} rounded according to the given rounding |
| * mode. |
| * @throws NullPointerException |
| * if {@code divisor == null} or {@code roundingMode == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @throws ArithmeticException |
| * if {@code roundingMode == RoundingMode.UNNECESSAR}Y and |
| * rounding is necessary according to the given scale and given |
| * precision. |
| */ |
| public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) { |
| // Let be: this = [u1,s1] and divisor = [u2,s2] |
| if (roundingMode == null) { |
| throw new NullPointerException("roundingMode == null"); |
| } |
| if (divisor.isZero()) { |
| throw new ArithmeticException("Division by zero"); |
| } |
| |
| long diffScale = ((long)this.scale - divisor.scale) - scale; |
| |
| // Check whether the diffScale will fit into an int. See http://b/17393664. |
| if (bitLength(diffScale) > 32) { |
| throw new ArithmeticException( |
| "Unable to perform divisor / dividend scaling: the difference in scale is too" + |
| " big (" + diffScale + ")"); |
| } |
| |
| if(this.bitLength < 64 && divisor.bitLength < 64 ) { |
| if(diffScale == 0) { |
| // http://b/26105053 - corner case: Long.MIN_VALUE / (-1) overflows a long |
| if (this.smallValue != Long.MIN_VALUE || divisor.smallValue != -1) { |
| return dividePrimitiveLongs(this.smallValue, |
| divisor.smallValue, |
| scale, |
| roundingMode); |
| } |
| } else if(diffScale > 0) { |
| if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length && |
| divisor.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)diffScale] < 64) { |
| return dividePrimitiveLongs(this.smallValue, |
| divisor.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)diffScale], |
| scale, |
| roundingMode); |
| } |
| } else { // diffScale < 0 |
| if(-diffScale < MathUtils.LONG_POWERS_OF_TEN.length && |
| this.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)-diffScale] < 64) { |
| return dividePrimitiveLongs(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)-diffScale], |
| divisor.smallValue, |
| scale, |
| roundingMode); |
| } |
| |
| } |
| } |
| BigInteger scaledDividend = this.getUnscaledValue(); |
| BigInteger scaledDivisor = divisor.getUnscaledValue(); // for scaling of 'u2' |
| |
| if (diffScale > 0) { |
| // Multiply 'u2' by: 10^((s1 - s2) - scale) |
| scaledDivisor = Multiplication.multiplyByTenPow(scaledDivisor, (int)diffScale); |
| } else if (diffScale < 0) { |
| // Multiply 'u1' by: 10^(scale - (s1 - s2)) |
| scaledDividend = Multiplication.multiplyByTenPow(scaledDividend, (int)-diffScale); |
| } |
| return divideBigIntegers(scaledDividend, scaledDivisor, scale, roundingMode); |
| } |
| |
| private static BigDecimal divideBigIntegers(BigInteger scaledDividend, BigInteger scaledDivisor, int scale, RoundingMode roundingMode) { |
| |
| BigInteger[] quotAndRem = scaledDividend.divideAndRemainder(scaledDivisor); // quotient and remainder |
| // If after division there is a remainder... |
| BigInteger quotient = quotAndRem[0]; |
| BigInteger remainder = quotAndRem[1]; |
| if (remainder.signum() == 0) { |
| return new BigDecimal(quotient, scale); |
| } |
| int sign = scaledDividend.signum() * scaledDivisor.signum(); |
| int compRem; // 'compare to remainder' |
| if(scaledDivisor.bitLength() < 63) { // 63 in order to avoid out of long after *2 |
| long rem = remainder.longValue(); |
| long divisor = scaledDivisor.longValue(); |
| compRem = compareForRounding(rem, divisor); |
| // To look if there is a carry |
| compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0, |
| sign * (5 + compRem), roundingMode); |
| |
| } else { |
| // Checking if: remainder * 2 >= scaledDivisor |
| compRem = remainder.abs().shiftLeftOneBit().compareTo(scaledDivisor.abs()); |
| compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0, |
| sign * (5 + compRem), roundingMode); |
| } |
| if (compRem != 0) { |
| if(quotient.bitLength() < 63) { |
| return valueOf(quotient.longValue() + compRem,scale); |
| } |
| quotient = quotient.add(BigInteger.valueOf(compRem)); |
| return new BigDecimal(quotient, scale); |
| } |
| // Constructing the result with the appropriate unscaled value |
| return new BigDecimal(quotient, scale); |
| } |
| |
| private static BigDecimal dividePrimitiveLongs(long scaledDividend, long scaledDivisor, int scale, RoundingMode roundingMode) { |
| long quotient = scaledDividend / scaledDivisor; |
| long remainder = scaledDividend % scaledDivisor; |
| int sign = Long.signum( scaledDividend ) * Long.signum( scaledDivisor ); |
| if (remainder != 0) { |
| // Checking if: remainder * 2 >= scaledDivisor |
| int compRem = compareForRounding(remainder, scaledDivisor); // 'compare to remainder' |
| // To look if there is a carry |
| quotient += roundingBehavior(((int)quotient) & 1, |
| sign * (5 + compRem), |
| roundingMode); |
| } |
| // Constructing the result with the appropriate unscaled value |
| return valueOf(quotient, scale); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this / divisor}. |
| * The scale of the result is the scale of {@code this}. If rounding is |
| * required to meet the specified scale, then the specified rounding mode |
| * {@code roundingMode} is applied. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @param roundingMode |
| * rounding mode to be used to round the result. |
| * @return {@code this / divisor} rounded according to the given rounding |
| * mode. |
| * @throws NullPointerException |
| * if {@code divisor == null}. |
| * @throws IllegalArgumentException |
| * if {@code roundingMode} is not a valid rounding mode. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @throws ArithmeticException |
| * if {@code roundingMode == ROUND_UNNECESSARY} and rounding is |
| * necessary according to the scale of this. |
| */ |
| public BigDecimal divide(BigDecimal divisor, int roundingMode) { |
| return divide(divisor, scale, RoundingMode.valueOf(roundingMode)); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this / divisor}. |
| * The scale of the result is the scale of {@code this}. If rounding is |
| * required to meet the specified scale, then the specified rounding mode |
| * {@code roundingMode} is applied. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @param roundingMode |
| * rounding mode to be used to round the result. |
| * @return {@code this / divisor} rounded according to the given rounding |
| * mode. |
| * @throws NullPointerException |
| * if {@code divisor == null} or {@code roundingMode == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @throws ArithmeticException |
| * if {@code roundingMode == RoundingMode.UNNECESSARY} and |
| * rounding is necessary according to the scale of this. |
| */ |
| public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) { |
| return divide(divisor, scale, roundingMode); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this / divisor}. |
| * The scale of the result is the difference of the scales of {@code this} |
| * and {@code divisor}. If the exact result requires more digits, then the |
| * scale is adjusted accordingly. For example, {@code 1/128 = 0.0078125} |
| * which has a scale of {@code 7} and precision {@code 5}. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @return {@code this / divisor}. |
| * @throws NullPointerException |
| * if {@code divisor == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @throws ArithmeticException |
| * if the result cannot be represented exactly. |
| */ |
| public BigDecimal divide(BigDecimal divisor) { |
| BigInteger p = this.getUnscaledValue(); |
| BigInteger q = divisor.getUnscaledValue(); |
| BigInteger gcd; // greatest common divisor between 'p' and 'q' |
| BigInteger quotAndRem[]; |
| long diffScale = (long)scale - divisor.scale; |
| int newScale; // the new scale for final quotient |
| int k; // number of factors "2" in 'q' |
| int l = 0; // number of factors "5" in 'q' |
| int i = 1; |
| int lastPow = FIVE_POW.length - 1; |
| |
| if (divisor.isZero()) { |
| throw new ArithmeticException("Division by zero"); |
| } |
| if (p.signum() == 0) { |
| return zeroScaledBy(diffScale); |
| } |
| // To divide both by the GCD |
| gcd = p.gcd(q); |
| p = p.divide(gcd); |
| q = q.divide(gcd); |
| // To simplify all "2" factors of q, dividing by 2^k |
| k = q.getLowestSetBit(); |
| q = q.shiftRight(k); |
| // To simplify all "5" factors of q, dividing by 5^l |
| do { |
| quotAndRem = q.divideAndRemainder(FIVE_POW[i]); |
| if (quotAndRem[1].signum() == 0) { |
| l += i; |
| if (i < lastPow) { |
| i++; |
| } |
| q = quotAndRem[0]; |
| } else { |
| if (i == 1) { |
| break; |
| } |
| i = 1; |
| } |
| } while (true); |
| // If abs(q) != 1 then the quotient is periodic |
| if (!q.abs().equals(BigInteger.ONE)) { |
| throw new ArithmeticException("Non-terminating decimal expansion; no exact representable decimal result"); |
| } |
| // The sign of the is fixed and the quotient will be saved in 'p' |
| if (q.signum() < 0) { |
| p = p.negate(); |
| } |
| // Checking if the new scale is out of range |
| newScale = safeLongToInt(diffScale + Math.max(k, l)); |
| // k >= 0 and l >= 0 implies that k - l is in the 32-bit range |
| i = k - l; |
| |
| p = (i > 0) ? Multiplication.multiplyByFivePow(p, i) |
| : p.shiftLeft(-i); |
| return new BigDecimal(p, newScale); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this / divisor}. |
| * The result is rounded according to the passed context {@code mc}. If the |
| * passed math context specifies precision {@code 0}, then this call is |
| * equivalent to {@code this.divide(divisor)}. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @return {@code this / divisor}. |
| * @throws NullPointerException |
| * if {@code divisor == null} or {@code mc == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @throws ArithmeticException |
| * if {@code mc.getRoundingMode() == UNNECESSARY} and rounding |
| * is necessary according {@code mc.getPrecision()}. |
| */ |
| public BigDecimal divide(BigDecimal divisor, MathContext mc) { |
| /* Calculating how many zeros must be append to 'dividend' |
| * to obtain a quotient with at least 'mc.precision()' digits */ |
| long trailingZeros = mc.getPrecision() + 2L |
| + divisor.approxPrecision() - approxPrecision(); |
| long diffScale = (long)scale - divisor.scale; |
| long newScale = diffScale; // scale of the final quotient |
| int compRem; // to compare the remainder |
| int i = 1; // index |
| int lastPow = TEN_POW.length - 1; // last power of ten |
| BigInteger integerQuot; // for temporal results |
| BigInteger quotAndRem[] = {getUnscaledValue()}; |
| // In special cases it reduces the problem to call the dual method |
| if ((mc.getPrecision() == 0) || (this.isZero()) |
| || (divisor.isZero())) { |
| return this.divide(divisor); |
| } |
| if (trailingZeros > 0) { |
| // To append trailing zeros at end of dividend |
| quotAndRem[0] = getUnscaledValue().multiply( Multiplication.powerOf10(trailingZeros) ); |
| newScale += trailingZeros; |
| } |
| quotAndRem = quotAndRem[0].divideAndRemainder( divisor.getUnscaledValue() ); |
| integerQuot = quotAndRem[0]; |
| // Calculating the exact quotient with at least 'mc.precision()' digits |
| if (quotAndRem[1].signum() != 0) { |
| // Checking if: 2 * remainder >= divisor ? |
| compRem = quotAndRem[1].shiftLeftOneBit().compareTo( divisor.getUnscaledValue() ); |
| // quot := quot * 10 + r; with 'r' in {-6,-5,-4, 0,+4,+5,+6} |
| integerQuot = integerQuot.multiply(BigInteger.TEN) |
| .add(BigInteger.valueOf(quotAndRem[0].signum() * (5 + compRem))); |
| newScale++; |
| } else { |
| // To strip trailing zeros until the preferred scale is reached |
| while (!integerQuot.testBit(0)) { |
| quotAndRem = integerQuot.divideAndRemainder(TEN_POW[i]); |
| if ((quotAndRem[1].signum() == 0) |
| && (newScale - i >= diffScale)) { |
| newScale -= i; |
| if (i < lastPow) { |
| i++; |
| } |
| integerQuot = quotAndRem[0]; |
| } else { |
| if (i == 1) { |
| break; |
| } |
| i = 1; |
| } |
| } |
| } |
| // To perform rounding |
| return new BigDecimal(integerQuot, safeLongToInt(newScale), mc); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is the integral part of |
| * {@code this / divisor}. The quotient is rounded down towards zero to the |
| * next integer. For example, {@code 0.5/0.2 = 2}. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @return integral part of {@code this / divisor}. |
| * @throws NullPointerException |
| * if {@code divisor == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| */ |
| public BigDecimal divideToIntegralValue(BigDecimal divisor) { |
| BigInteger integralValue; // the integer of result |
| BigInteger powerOfTen; // some power of ten |
| |
| long newScale = (long)this.scale - divisor.scale; |
| long tempScale = 0; |
| int i = 1; |
| int lastPow = TEN_POW.length - 1; |
| |
| if (divisor.isZero()) { |
| throw new ArithmeticException("Division by zero"); |
| } |
| if ((divisor.approxPrecision() + newScale > this.approxPrecision() + 1L) |
| || (this.isZero())) { |
| /* If the divisor's integer part is greater than this's integer part, |
| * the result must be zero with the appropriate scale */ |
| integralValue = BigInteger.ZERO; |
| } else if (newScale == 0) { |
| integralValue = getUnscaledValue().divide( divisor.getUnscaledValue() ); |
| } else if (newScale > 0) { |
| powerOfTen = Multiplication.powerOf10(newScale); |
| integralValue = getUnscaledValue().divide( divisor.getUnscaledValue().multiply(powerOfTen) ); |
| integralValue = integralValue.multiply(powerOfTen); |
| } else {// (newScale < 0) |
| powerOfTen = Multiplication.powerOf10(-newScale); |
| integralValue = getUnscaledValue().multiply(powerOfTen).divide( divisor.getUnscaledValue() ); |
| // To strip trailing zeros approximating to the preferred scale |
| while (!integralValue.testBit(0)) { |
| BigInteger[] quotAndRem = integralValue.divideAndRemainder(TEN_POW[i]); |
| if ((quotAndRem[1].signum() == 0) |
| && (tempScale - i >= newScale)) { |
| tempScale -= i; |
| if (i < lastPow) { |
| i++; |
| } |
| integralValue = quotAndRem[0]; |
| } else { |
| if (i == 1) { |
| break; |
| } |
| i = 1; |
| } |
| } |
| newScale = tempScale; |
| } |
| return ((integralValue.signum() == 0) |
| ? zeroScaledBy(newScale) |
| : new BigDecimal(integralValue, safeLongToInt(newScale))); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is the integral part of |
| * {@code this / divisor}. The quotient is rounded down towards zero to the |
| * next integer. The rounding mode passed with the parameter {@code mc} is |
| * not considered. But if the precision of {@code mc > 0} and the integral |
| * part requires more digits, then an {@code ArithmeticException} is thrown. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @param mc |
| * math context which determines the maximal precision of the |
| * result. |
| * @return integral part of {@code this / divisor}. |
| * @throws NullPointerException |
| * if {@code divisor == null} or {@code mc == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @throws ArithmeticException |
| * if {@code mc.getPrecision() > 0} and the result requires more |
| * digits to be represented. |
| */ |
| public BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) { |
| int mcPrecision = mc.getPrecision(); |
| int diffPrecision = this.precision() - divisor.precision(); |
| int lastPow = TEN_POW.length - 1; |
| long diffScale = (long)this.scale - divisor.scale; |
| long newScale = diffScale; |
| long quotPrecision = diffPrecision - diffScale + 1; |
| BigInteger quotAndRem[] = new BigInteger[2]; |
| // In special cases it call the dual method |
| if ((mcPrecision == 0) || (this.isZero()) || (divisor.isZero())) { |
| return this.divideToIntegralValue(divisor); |
| } |
| // Let be: this = [u1,s1] and divisor = [u2,s2] |
| if (quotPrecision <= 0) { |
| quotAndRem[0] = BigInteger.ZERO; |
| } else if (diffScale == 0) { |
| // CASE s1 == s2: to calculate u1 / u2 |
| quotAndRem[0] = this.getUnscaledValue().divide( divisor.getUnscaledValue() ); |
| } else if (diffScale > 0) { |
| // CASE s1 >= s2: to calculate u1 / (u2 * 10^(s1-s2) |
| quotAndRem[0] = this.getUnscaledValue().divide( |
| divisor.getUnscaledValue().multiply(Multiplication.powerOf10(diffScale)) ); |
| // To chose 10^newScale to get a quotient with at least 'mc.precision()' digits |
| newScale = Math.min(diffScale, Math.max(mcPrecision - quotPrecision + 1, 0)); |
| // To calculate: (u1 / (u2 * 10^(s1-s2)) * 10^newScale |
| quotAndRem[0] = quotAndRem[0].multiply(Multiplication.powerOf10(newScale)); |
| } else {// CASE s2 > s1: |
| /* To calculate the minimum power of ten, such that the quotient |
| * (u1 * 10^exp) / u2 has at least 'mc.precision()' digits. */ |
| long exp = Math.min(-diffScale, Math.max((long)mcPrecision - diffPrecision, 0)); |
| long compRemDiv; |
| // Let be: (u1 * 10^exp) / u2 = [q,r] |
| quotAndRem = this.getUnscaledValue().multiply(Multiplication.powerOf10(exp)). |
| divideAndRemainder(divisor.getUnscaledValue()); |
| newScale += exp; // To fix the scale |
| exp = -newScale; // The remaining power of ten |
| // If after division there is a remainder... |
| if ((quotAndRem[1].signum() != 0) && (exp > 0)) { |
| // Log10(r) + ((s2 - s1) - exp) > mc.precision ? |
| compRemDiv = (new BigDecimal(quotAndRem[1])).precision() |
| + exp - divisor.precision(); |
| if (compRemDiv == 0) { |
| // To calculate: (r * 10^exp2) / u2 |
| quotAndRem[1] = quotAndRem[1].multiply(Multiplication.powerOf10(exp)). |
| divide(divisor.getUnscaledValue()); |
| compRemDiv = Math.abs(quotAndRem[1].signum()); |
| } |
| if (compRemDiv > 0) { |
| throw new ArithmeticException("Division impossible"); |
| } |
| } |
| } |
| // Fast return if the quotient is zero |
| if (quotAndRem[0].signum() == 0) { |
| return zeroScaledBy(diffScale); |
| } |
| BigInteger strippedBI = quotAndRem[0]; |
| BigDecimal integralValue = new BigDecimal(quotAndRem[0]); |
| long resultPrecision = integralValue.precision(); |
| int i = 1; |
| // To strip trailing zeros until the specified precision is reached |
| while (!strippedBI.testBit(0)) { |
| quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]); |
| if ((quotAndRem[1].signum() == 0) && |
| ((resultPrecision - i >= mcPrecision) |
| || (newScale - i >= diffScale)) ) { |
| resultPrecision -= i; |
| newScale -= i; |
| if (i < lastPow) { |
| i++; |
| } |
| strippedBI = quotAndRem[0]; |
| } else { |
| if (i == 1) { |
| break; |
| } |
| i = 1; |
| } |
| } |
| // To check if the result fit in 'mc.precision()' digits |
| if (resultPrecision > mcPrecision) { |
| throw new ArithmeticException("Division impossible"); |
| } |
| integralValue.scale = safeLongToInt(newScale); |
| integralValue.setUnscaledValue(strippedBI); |
| return integralValue; |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this % divisor}. |
| * <p> |
| * The remainder is defined as {@code this - |
| * this.divideToIntegralValue(divisor) * divisor}. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @return {@code this % divisor}. |
| * @throws NullPointerException |
| * if {@code divisor == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| */ |
| public BigDecimal remainder(BigDecimal divisor) { |
| return divideAndRemainder(divisor)[1]; |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this % divisor}. |
| * <p> |
| * The remainder is defined as {@code this - |
| * this.divideToIntegralValue(divisor) * divisor}. |
| * <p> |
| * The specified rounding mode {@code mc} is used for the division only. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @param mc |
| * rounding mode and precision to be used. |
| * @return {@code this % divisor}. |
| * @throws NullPointerException |
| * if {@code divisor == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @throws ArithmeticException |
| * if {@code mc.getPrecision() > 0} and the result of {@code |
| * this.divideToIntegralValue(divisor, mc)} requires more digits |
| * to be represented. |
| */ |
| public BigDecimal remainder(BigDecimal divisor, MathContext mc) { |
| return divideAndRemainder(divisor, mc)[1]; |
| } |
| |
| /** |
| * Returns a {@code BigDecimal} array which contains the integral part of |
| * {@code this / divisor} at index 0 and the remainder {@code this % |
| * divisor} at index 1. The quotient is rounded down towards zero to the |
| * next integer. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @return {@code [this.divideToIntegralValue(divisor), |
| * this.remainder(divisor)]}. |
| * @throws NullPointerException |
| * if {@code divisor == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @see #divideToIntegralValue |
| * @see #remainder |
| */ |
| public BigDecimal[] divideAndRemainder(BigDecimal divisor) { |
| BigDecimal quotAndRem[] = new BigDecimal[2]; |
| |
| quotAndRem[0] = this.divideToIntegralValue(divisor); |
| quotAndRem[1] = this.subtract( quotAndRem[0].multiply(divisor) ); |
| return quotAndRem; |
| } |
| |
| /** |
| * Returns a {@code BigDecimal} array which contains the integral part of |
| * {@code this / divisor} at index 0 and the remainder {@code this % |
| * divisor} at index 1. The quotient is rounded down towards zero to the |
| * next integer. The rounding mode passed with the parameter {@code mc} is |
| * not considered. But if the precision of {@code mc > 0} and the integral |
| * part requires more digits, then an {@code ArithmeticException} is thrown. |
| * |
| * @param divisor |
| * value by which {@code this} is divided. |
| * @param mc |
| * math context which determines the maximal precision of the |
| * result. |
| * @return {@code [this.divideToIntegralValue(divisor), |
| * this.remainder(divisor)]}. |
| * @throws NullPointerException |
| * if {@code divisor == null}. |
| * @throws ArithmeticException |
| * if {@code divisor == 0}. |
| * @see #divideToIntegralValue |
| * @see #remainder |
| */ |
| public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) { |
| BigDecimal quotAndRem[] = new BigDecimal[2]; |
| |
| quotAndRem[0] = this.divideToIntegralValue(divisor, mc); |
| quotAndRem[1] = this.subtract( quotAndRem[0].multiply(divisor) ); |
| return quotAndRem; |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this<sup>n</sup>}. The |
| * scale of the result is {@code n * this.scale()}. |
| * |
| * <p>{@code x.pow(0)} returns {@code 1}, even if {@code x == 0}. |
| * |
| * <p>Implementation Note: The implementation is based on the ANSI standard |
| * X3.274-1996 algorithm. |
| * |
| * @throws ArithmeticException |
| * if {@code n < 0} or {@code n > 999999999}. |
| */ |
| public BigDecimal pow(int n) { |
| if (n == 0) { |
| return ONE; |
| } |
| if ((n < 0) || (n > 999999999)) { |
| throw new ArithmeticException("Invalid operation"); |
| } |
| long newScale = scale * (long)n; |
| // Let be: this = [u,s] so: this^n = [u^n, s*n] |
| return isZero() ? zeroScaledBy(newScale) |
| : new BigDecimal(getUnscaledValue().pow(n), safeLongToInt(newScale)); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this<sup>n</sup>}. The |
| * result is rounded according to the passed context {@code mc}. |
| * |
| * <p>Implementation Note: The implementation is based on the ANSI standard |
| * X3.274-1996 algorithm. |
| * |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @throws ArithmeticException |
| * if {@code n < 0} or {@code n > 999999999}. |
| */ |
| public BigDecimal pow(int n, MathContext mc) { |
| // The ANSI standard X3.274-1996 algorithm |
| int m = Math.abs(n); |
| int mcPrecision = mc.getPrecision(); |
| int elength = (int)Math.log10(m) + 1; // decimal digits in 'n' |
| int oneBitMask; // mask of bits |
| BigDecimal accum; // the single accumulator |
| MathContext newPrecision = mc; // MathContext by default |
| |
| // In particular cases, it reduces the problem to call the other 'pow()' |
| if ((n == 0) || ((isZero()) && (n > 0))) { |
| return pow(n); |
| } |
| if ((m > 999999999) || ((mcPrecision == 0) && (n < 0)) |
| || ((mcPrecision > 0) && (elength > mcPrecision))) { |
| throw new ArithmeticException("Invalid operation"); |
| } |
| if (mcPrecision > 0) { |
| newPrecision = new MathContext( mcPrecision + elength + 1, |
| mc.getRoundingMode()); |
| } |
| // The result is calculated as if 'n' were positive |
| accum = round(newPrecision); |
| oneBitMask = Integer.highestOneBit(m) >> 1; |
| |
| while (oneBitMask > 0) { |
| accum = accum.multiply(accum, newPrecision); |
| if ((m & oneBitMask) == oneBitMask) { |
| accum = accum.multiply(this, newPrecision); |
| } |
| oneBitMask >>= 1; |
| } |
| // If 'n' is negative, the value is divided into 'ONE' |
| if (n < 0) { |
| accum = ONE.divide(accum, newPrecision); |
| } |
| // The final value is rounded to the destination precision |
| accum.inplaceRound(mc); |
| return accum; |
| } |
| |
| /** |
| * Returns a {@code BigDecimal} whose value is the absolute value of |
| * {@code this}. The scale of the result is the same as the scale of this. |
| */ |
| public BigDecimal abs() { |
| return ((signum() < 0) ? negate() : this); |
| } |
| |
| /** |
| * Returns a {@code BigDecimal} whose value is the absolute value of |
| * {@code this}. The result is rounded according to the passed context |
| * {@code mc}. |
| */ |
| public BigDecimal abs(MathContext mc) { |
| BigDecimal result = (signum() < 0) ? negate() : new BigDecimal(getUnscaledValue(), scale); |
| result.inplaceRound(mc); |
| return result; |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is the {@code -this}. The |
| * scale of the result is the same as the scale of this. |
| * |
| * @return {@code -this} |
| */ |
| public BigDecimal negate() { |
| if(bitLength < 63 || (bitLength == 63 && smallValue!=Long.MIN_VALUE)) { |
| return valueOf(-smallValue,scale); |
| } |
| return new BigDecimal(getUnscaledValue().negate(), scale); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is the {@code -this}. The |
| * result is rounded according to the passed context {@code mc}. |
| * |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @return {@code -this} |
| */ |
| public BigDecimal negate(MathContext mc) { |
| BigDecimal result = negate(); |
| result.inplaceRound(mc); |
| return result; |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code +this}. The scale |
| * of the result is the same as the scale of this. |
| * |
| * @return {@code this} |
| */ |
| public BigDecimal plus() { |
| return this; |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code +this}. The result |
| * is rounded according to the passed context {@code mc}. |
| * |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @return {@code this}, rounded |
| */ |
| public BigDecimal plus(MathContext mc) { |
| return round(mc); |
| } |
| |
| /** |
| * Returns the sign of this {@code BigDecimal}. |
| * |
| * @return {@code -1} if {@code this < 0}, |
| * {@code 0} if {@code this == 0}, |
| * {@code 1} if {@code this > 0}. |
| */ |
| public int signum() { |
| if( bitLength < 64) { |
| return Long.signum( this.smallValue ); |
| } |
| return getUnscaledValue().signum(); |
| } |
| |
| private boolean isZero() { |
| //Watch out: -1 has a bitLength=0 |
| return bitLength == 0 && this.smallValue != -1; |
| } |
| |
| /** |
| * Returns the scale of this {@code BigDecimal}. The scale is the number of |
| * digits behind the decimal point. The value of this {@code BigDecimal} is |
| * the {@code unsignedValue * 10<sup>-scale</sup>}. If the scale is negative, |
| * then this {@code BigDecimal} represents a big integer. |
| * |
| * @return the scale of this {@code BigDecimal}. |
| */ |
| public int scale() { |
| return scale; |
| } |
| |
| /** |
| * Returns the precision of this {@code BigDecimal}. The precision is the |
| * number of decimal digits used to represent this decimal. It is equivalent |
| * to the number of digits of the unscaled value. The precision of {@code 0} |
| * is {@code 1} (independent of the scale). |
| * |
| * @return the precision of this {@code BigDecimal}. |
| */ |
| public int precision() { |
| // Return the cached value if we have one. |
| if (precision != 0) { |
| return precision; |
| } |
| |
| if (bitLength == 0) { |
| precision = 1; |
| } else if (bitLength < 64) { |
| precision = decimalDigitsInLong(smallValue); |
| } else { |
| int decimalDigits = 1 + (int) ((bitLength - 1) * LOG10_2); |
| // If after division the number isn't zero, there exists an additional digit |
| if (getUnscaledValue().divide(Multiplication.powerOf10(decimalDigits)).signum() != 0) { |
| decimalDigits++; |
| } |
| precision = decimalDigits; |
| } |
| return precision; |
| } |
| |
| private int decimalDigitsInLong(long value) { |
| if (value == Long.MIN_VALUE) { |
| return 19; // special case required because abs(MIN_VALUE) == MIN_VALUE |
| } else { |
| int index = Arrays.binarySearch(MathUtils.LONG_POWERS_OF_TEN, Math.abs(value)); |
| return (index < 0) ? (-index - 1) : (index + 1); |
| } |
| } |
| |
| /** |
| * Returns the unscaled value (mantissa) of this {@code BigDecimal} instance |
| * as a {@code BigInteger}. The unscaled value can be computed as |
| * {@code this * 10<sup>scale</sup>}. |
| */ |
| public BigInteger unscaledValue() { |
| return getUnscaledValue(); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this}, rounded |
| * according to the passed context {@code mc}. |
| * <p> |
| * If {@code mc.precision = 0}, then no rounding is performed. |
| * <p> |
| * If {@code mc.precision > 0} and {@code mc.roundingMode == UNNECESSARY}, |
| * then an {@code ArithmeticException} is thrown if the result cannot be |
| * represented exactly within the given precision. |
| * |
| * @param mc |
| * rounding mode and precision for the result of this operation. |
| * @return {@code this} rounded according to the passed context. |
| * @throws ArithmeticException |
| * if {@code mc.precision > 0} and {@code mc.roundingMode == |
| * UNNECESSARY} and this cannot be represented within the given |
| * precision. |
| */ |
| public BigDecimal round(MathContext mc) { |
| BigDecimal thisBD = new BigDecimal(getUnscaledValue(), scale); |
| |
| thisBD.inplaceRound(mc); |
| return thisBD; |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} instance with the specified scale. |
| * <p> |
| * If the new scale is greater than the old scale, then additional zeros are |
| * added to the unscaled value. In this case no rounding is necessary. |
| * <p> |
| * If the new scale is smaller than the old scale, then trailing digits are |
| * removed. If these trailing digits are not zero, then the remaining |
| * unscaled value has to be rounded. For this rounding operation the |
| * specified rounding mode is used. |
| * |
| * @param newScale |
| * scale of the result returned. |
| * @param roundingMode |
| * rounding mode to be used to round the result. |
| * @return a new {@code BigDecimal} instance with the specified scale. |
| * @throws NullPointerException |
| * if {@code roundingMode == null}. |
| * @throws ArithmeticException |
| * if {@code roundingMode == ROUND_UNNECESSARY} and rounding is |
| * necessary according to the given scale. |
| */ |
| public BigDecimal setScale(int newScale, RoundingMode roundingMode) { |
| if (roundingMode == null) { |
| throw new NullPointerException("roundingMode == null"); |
| } |
| long diffScale = newScale - (long)scale; |
| // Let be: 'this' = [u,s] |
| if(diffScale == 0) { |
| return this; |
| } |
| if(diffScale > 0) { |
| // return [u * 10^(s2 - s), newScale] |
| if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length && |
| (this.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)diffScale]) < 64 ) { |
| return valueOf(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)diffScale],newScale); |
| } |
| return new BigDecimal(Multiplication.multiplyByTenPow(getUnscaledValue(),(int)diffScale), newScale); |
| } |
| // diffScale < 0 |
| // return [u,s] / [1,newScale] with the appropriate scale and rounding |
| if(this.bitLength < 64 && -diffScale < MathUtils.LONG_POWERS_OF_TEN.length) { |
| return dividePrimitiveLongs(this.smallValue, MathUtils.LONG_POWERS_OF_TEN[(int)-diffScale], newScale,roundingMode); |
| } |
| return divideBigIntegers(this.getUnscaledValue(),Multiplication.powerOf10(-diffScale),newScale,roundingMode); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} instance with the specified scale. |
| * <p> |
| * If the new scale is greater than the old scale, then additional zeros are |
| * added to the unscaled value. In this case no rounding is necessary. |
| * <p> |
| * If the new scale is smaller than the old scale, then trailing digits are |
| * removed. If these trailing digits are not zero, then the remaining |
| * unscaled value has to be rounded. For this rounding operation the |
| * specified rounding mode is used. |
| * |
| * @param newScale |
| * scale of the result returned. |
| * @param roundingMode |
| * rounding mode to be used to round the result. |
| * @return a new {@code BigDecimal} instance with the specified scale. |
| * @throws IllegalArgumentException |
| * if {@code roundingMode} is not a valid rounding mode. |
| * @throws ArithmeticException |
| * if {@code roundingMode == ROUND_UNNECESSARY} and rounding is |
| * necessary according to the given scale. |
| */ |
| public BigDecimal setScale(int newScale, int roundingMode) { |
| return setScale(newScale, RoundingMode.valueOf(roundingMode)); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} instance with the specified scale. If |
| * the new scale is greater than the old scale, then additional zeros are |
| * added to the unscaled value. If the new scale is smaller than the old |
| * scale, then trailing zeros are removed. If the trailing digits are not |
| * zeros then an ArithmeticException is thrown. |
| * <p> |
| * If no exception is thrown, then the following equation holds: {@code |
| * x.setScale(s).compareTo(x) == 0}. |
| * |
| * @param newScale |
| * scale of the result returned. |
| * @return a new {@code BigDecimal} instance with the specified scale. |
| * @throws ArithmeticException |
| * if rounding would be necessary. |
| */ |
| public BigDecimal setScale(int newScale) { |
| return setScale(newScale, RoundingMode.UNNECESSARY); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} instance where the decimal point has |
| * been moved {@code n} places to the left. If {@code n < 0} then the |
| * decimal point is moved {@code -n} places to the right. |
| * |
| * <p>The result is obtained by changing its scale. If the scale of the result |
| * becomes negative, then its precision is increased such that the scale is |
| * zero. |
| * |
| * <p>Note, that {@code movePointLeft(0)} returns a result which is |
| * mathematically equivalent, but which has {@code scale >= 0}. |
| */ |
| public BigDecimal movePointLeft(int n) { |
| return movePoint(scale + (long)n); |
| } |
| |
| private BigDecimal movePoint(long newScale) { |
| if (isZero()) { |
| return zeroScaledBy(Math.max(newScale, 0)); |
| } |
| /* |
| * When: 'n'== Integer.MIN_VALUE isn't possible to call to |
| * movePointRight(-n) since -Integer.MIN_VALUE == Integer.MIN_VALUE |
| */ |
| if(newScale >= 0) { |
| if(bitLength < 64) { |
| return valueOf(smallValue, safeLongToInt(newScale)); |
| } |
| return new BigDecimal(getUnscaledValue(), safeLongToInt(newScale)); |
| } |
| if(-newScale < MathUtils.LONG_POWERS_OF_TEN.length && |
| bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)-newScale] < 64 ) { |
| return valueOf(smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)-newScale],0); |
| } |
| return new BigDecimal(Multiplication.multiplyByTenPow( |
| getUnscaledValue(), safeLongToInt(-newScale)), 0); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} instance where the decimal point has |
| * been moved {@code n} places to the right. If {@code n < 0} then the |
| * decimal point is moved {@code -n} places to the left. |
| * |
| * <p>The result is obtained by changing its scale. If the scale of the result |
| * becomes negative, then its precision is increased such that the scale is |
| * zero. |
| * |
| * <p>Note, that {@code movePointRight(0)} returns a result which is |
| * mathematically equivalent, but which has scale >= 0. |
| */ |
| public BigDecimal movePointRight(int n) { |
| return movePoint(scale - (long)n); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} whose value is {@code this * 10<sup>n</sup>}. |
| * The scale of the result is {@code this.scale()} - {@code n}. |
| * The precision of the result is the precision of {@code this}. |
| * |
| * <p>This method has the same effect as {@link #movePointRight}, except that |
| * the precision is not changed. |
| */ |
| public BigDecimal scaleByPowerOfTen(int n) { |
| long newScale = scale - (long)n; |
| if(bitLength < 64) { |
| //Taking care when a 0 is to be scaled |
| if( smallValue==0 ){ |
| return zeroScaledBy( newScale ); |
| } |
| return valueOf(smallValue, safeLongToInt(newScale)); |
| } |
| return new BigDecimal(getUnscaledValue(), safeLongToInt(newScale)); |
| } |
| |
| /** |
| * Returns a new {@code BigDecimal} instance with the same value as {@code |
| * this} but with a unscaled value where the trailing zeros have been |
| * removed. If the unscaled value of {@code this} has n trailing zeros, then |
| * the scale and the precision of the result has been reduced by n. |
| * |
| * @return a new {@code BigDecimal} instance equivalent to this where the |
| * trailing zeros of the unscaled value have been removed. |
| */ |
| public BigDecimal stripTrailingZeros() { |
| int i = 1; // 1 <= i <= 18 |
| int lastPow = TEN_POW.length - 1; |
| long newScale = scale; |
| |
| if (isZero()) { |
| // Preserve RI compatibility, so BigDecimal.equals (which checks |
| // value *and* scale) continues to work. |
| return this; |
| } |
| BigInteger strippedBI = getUnscaledValue(); |
| BigInteger[] quotAndRem; |
| |
| // while the number is even... |
| while (!strippedBI.testBit(0)) { |
| // To divide by 10^i |
| quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]); |
| // To look the remainder |
| if (quotAndRem[1].signum() == 0) { |
| // To adjust the scale |
| newScale -= i; |
| if (i < lastPow) { |
| // To set to the next power |
| i++; |
| } |
| strippedBI = quotAndRem[0]; |
| } else { |
| if (i == 1) { |
| // 'this' has no more trailing zeros |
| break; |
| } |
| // To set to the smallest power of ten |
| i = 1; |
| } |
| } |
| return new BigDecimal(strippedBI, safeLongToInt(newScale)); |
| } |
| |
| /** |
| * Compares this {@code BigDecimal} with {@code val}. Returns one of the |
| * three values {@code 1}, {@code 0}, or {@code -1}. The method behaves as |
| * if {@code this.subtract(val)} is computed. If this difference is > 0 then |
| * 1 is returned, if the difference is < 0 then -1 is returned, and if the |
| * difference is 0 then 0 is returned. This means, that if two decimal |
| * instances are compared which are equal in value but differ in scale, then |
| * these two instances are considered as equal. |
| * |
| * @param val |
| * value to be compared with {@code this}. |
| * @return {@code 1} if {@code this > val}, {@code -1} if {@code this < val}, |
| * {@code 0} if {@code this == val}. |
| * @throws NullPointerException |
| * if {@code val == null}. |
| */ |
| public int compareTo(BigDecimal val) { |
| int thisSign = signum(); |
| int valueSign = val.signum(); |
| |
| if( thisSign == valueSign) { |
| if(this.scale == val.scale && this.bitLength<64 && val.bitLength<64 ) { |
| return (smallValue < val.smallValue) ? -1 : (smallValue > val.smallValue) ? 1 : 0; |
| } |
| long diffScale = (long)this.scale - val.scale; |
| int diffPrecision = this.approxPrecision() - val.approxPrecision(); |
| if (diffPrecision > diffScale + 1) { |
| return thisSign; |
| } else if (diffPrecision < diffScale - 1) { |
| return -thisSign; |
| } else {// thisSign == val.signum() and diffPrecision is aprox. diffScale |
| BigInteger thisUnscaled = this.getUnscaledValue(); |
| BigInteger valUnscaled = val.getUnscaledValue(); |
| // If any of both precision is bigger, append zeros to the shorter one |
| if (diffScale < 0) { |
| thisUnscaled = thisUnscaled.multiply(Multiplication.powerOf10(-diffScale)); |
| } else if (diffScale > 0) { |
| valUnscaled = valUnscaled.multiply(Multiplication.powerOf10(diffScale)); |
| } |
| return thisUnscaled.compareTo(valUnscaled); |
| } |
| } else if (thisSign < valueSign) { |
| return -1; |
| } else { |
| return 1; |
| } |
| } |
| |
| /** |
| * Returns {@code true} if {@code x} is a {@code BigDecimal} instance and if |
| * this instance is equal to this big decimal. Two big decimals are equal if |
| * their unscaled value and their scale is equal. For example, 1.0 |
| * (10*10<sup>-1</sup>) is not equal to 1.00 (100*10<sup>-2</sup>). Similarly, zero |
| * instances are not equal if their scale differs. |
| */ |
| @Override |
| public boolean equals(Object x) { |
| if (this == x) { |
| return true; |
| } |
| if (x instanceof BigDecimal) { |
| BigDecimal x1 = (BigDecimal) x; |
| return x1.scale == scale |
| && x1.bitLength == bitLength |
| && (bitLength < 64 ? (x1.smallValue == smallValue) : x1.intVal.equals(intVal)); |
| } |
| return false; |
| } |
| |
| /** |
| * Returns the minimum of this {@code BigDecimal} and {@code val}. |
| * |
| * @param val |
| * value to be used to compute the minimum with this. |
| * @return {@code min(this, val}. |
| * @throws NullPointerException |
| * if {@code val == null}. |
| */ |
| public BigDecimal min(BigDecimal val) { |
| return ((compareTo(val) <= 0) ? this : val); |
| } |
| |
| /** |
| * Returns the maximum of this {@code BigDecimal} and {@code val}. |
| * |
| * @param val |
| * value to be used to compute the maximum with this. |
| * @return {@code max(this, val}. |
| * @throws NullPointerException |
| * if {@code val == null}. |
| */ |
| public BigDecimal max(BigDecimal val) { |
| return ((compareTo(val) >= 0) ? this : val); |
| } |
| |
| /** |
| * Returns a hash code for this {@code BigDecimal}. |
| * |
| * @return hash code for {@code this}. |
| */ |
| @Override |
| public int hashCode() { |
| if (hashCode != 0) { |
| return hashCode; |
| } |
| if (bitLength < 64) { |
| hashCode = (int)(smallValue & 0xffffffff); |
| hashCode = 33 * hashCode + (int)((smallValue >> 32) & 0xffffffff); |
| hashCode = 17 * hashCode + scale; |
| return hashCode; |
| } |
| hashCode = 17 * intVal.hashCode() + scale; |
| return hashCode; |
| } |
| |
| /** |
| * Returns a canonical string representation of this {@code BigDecimal}. If |
| * necessary, scientific notation is used. This representation always prints |
| * all significant digits of this value. |
| * <p> |
| * If the scale is negative or if {@code scale - precision >= 6} then |
| * scientific notation is used. |
| * |
| * @return a string representation of {@code this} in scientific notation if |
| * necessary. |
| */ |
| @Override |
| public String toString() { |
| if (toStringImage != null) { |
| return toStringImage; |
| } |
| if(bitLength < 32) { |
| toStringImage = Conversion.toDecimalScaledString(smallValue,scale); |
| return toStringImage; |
| } |
| String intString = getUnscaledValue().toString(); |
| if (scale == 0) { |
| return intString; |
| } |
| int begin = (getUnscaledValue().signum() < 0) ? 2 : 1; |
| int end = intString.length(); |
| long exponent = -(long)scale + end - begin; |
| StringBuilder result = new StringBuilder(); |
| |
| result.append(intString); |
| if ((scale > 0) && (exponent >= -6)) { |
| if (exponent >= 0) { |
| result.insert(end - scale, '.'); |
| } else { |
| result.insert(begin - 1, "0."); |
| result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1); |
| } |
| } else { |
| if (end - begin >= 1) { |
| result.insert(begin, '.'); |
| end++; |
| } |
| result.insert(end, 'E'); |
| if (exponent > 0) { |
| result.insert(++end, '+'); |
| } |
| result.insert(++end, Long.toString(exponent)); |
| } |
| toStringImage = result.toString(); |
| return toStringImage; |
| } |
| |
| /** |
| * Returns a string representation of this {@code BigDecimal}. This |
| * representation always prints all significant digits of this value. |
| * <p> |
| * If the scale is negative or if {@code scale - precision >= 6} then |
| * engineering notation is used. Engineering notation is similar to the |
| * scientific notation except that the exponent is made to be a multiple of |
| * 3 such that the integer part is >= 1 and < 1000. |
| * |
| * @return a string representation of {@code this} in engineering notation |
| * if necessary. |
| */ |
| public String toEngineeringString() { |
| String intString = getUnscaledValue().toString(); |
| if (scale == 0) { |
| return intString; |
| } |
| int begin = (getUnscaledValue().signum() < 0) ? 2 : 1; |
| int end = intString.length(); |
| long exponent = -(long)scale + end - begin; |
| StringBuilder result = new StringBuilder(intString); |
| |
| if ((scale > 0) && (exponent >= -6)) { |
| if (exponent >= 0) { |
| result.insert(end - scale, '.'); |
| } else { |
| result.insert(begin - 1, "0."); |
| result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1); |
| } |
| } else { |
| int delta = end - begin; |
| int rem = (int)(exponent % 3); |
| |
| if (rem != 0) { |
| // adjust exponent so it is a multiple of three |
| if (getUnscaledValue().signum() == 0) { |
| // zero value |
| rem = (rem < 0) ? -rem : 3 - rem; |
| exponent += rem; |
| } else { |
| // nonzero value |
| rem = (rem < 0) ? rem + 3 : rem; |
| exponent -= rem; |
| begin += rem; |
| } |
| if (delta < 3) { |
| for (int i = rem - delta; i > 0; i--) { |
| result.insert(end++, '0'); |
| } |
| } |
| } |
| if (end - begin >= 1) { |
| result.insert(begin, '.'); |
| end++; |
| } |
| if (exponent != 0) { |
| result.insert(end, 'E'); |
| if (exponent > 0) { |
| result.insert(++end, '+'); |
| } |
| result.insert(++end, Long.toString(exponent)); |
| } |
| } |
| return result.toString(); |
| } |
| |
| /** |
| * Returns a string representation of this {@code BigDecimal}. No scientific |
| * notation is used. This methods adds zeros where necessary. |
| * <p> |
| * If this string representation is used to create a new instance, this |
| * instance is generally not identical to {@code this} as the precision |
| * changes. |
| * <p> |
| * {@code x.equals(new BigDecimal(x.toPlainString())} usually returns |
| * {@code false}. |
| * <p> |
| * {@code x.compareTo(new BigDecimal(x.toPlainString())} returns {@code 0}. |
| * |
| * @return a string representation of {@code this} without exponent part. |
| */ |
| public String toPlainString() { |
| String intStr = getUnscaledValue().toString(); |
| if ((scale == 0) || ((isZero()) && (scale < 0))) { |
| return intStr; |
| } |
| int begin = (signum() < 0) ? 1 : 0; |
| int delta = scale; |
| // We take space for all digits, plus a possible decimal point, plus 'scale' |
| StringBuilder result = new StringBuilder(intStr.length() + 1 + Math.abs(scale)); |
| |
| if (begin == 1) { |
| // If the number is negative, we insert a '-' character at front |
| result.append('-'); |
| } |
| if (scale > 0) { |
| delta -= (intStr.length() - begin); |
| if (delta >= 0) { |
| result.append("0."); |
| // To append zeros after the decimal point |
| for (; delta > CH_ZEROS.length; delta -= CH_ZEROS.length) { |
| result.append(CH_ZEROS); |
| } |
| result.append(CH_ZEROS, 0, delta); |
| result.append(intStr.substring(begin)); |
| } else { |
| delta = begin - delta; |
| result.append(intStr.substring(begin, delta)); |
| result.append('.'); |
| result.append(intStr.substring(delta)); |
| } |
| } else {// (scale <= 0) |
| result.append(intStr.substring(begin)); |
| // To append trailing zeros |
| for (; delta < -CH_ZEROS.length; delta += CH_ZEROS.length) { |
| result.append(CH_ZEROS); |
| } |
| result.append(CH_ZEROS, 0, -delta); |
| } |
| return result.toString(); |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as a big integer instance. A fractional |
| * part is discarded. |
| * |
| * @return this {@code BigDecimal} as a big integer instance. |
| */ |
| public BigInteger toBigInteger() { |
| if ((scale == 0) || (isZero())) { |
| return getUnscaledValue(); |
| } else if (scale < 0) { |
| return getUnscaledValue().multiply(Multiplication.powerOf10(-(long)scale)); |
| } else {// (scale > 0) |
| return getUnscaledValue().divide(Multiplication.powerOf10(scale)); |
| } |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as a big integer instance if it has no |
| * fractional part. If this {@code BigDecimal} has a fractional part, i.e. |
| * if rounding would be necessary, an {@code ArithmeticException} is thrown. |
| * |
| * @return this {@code BigDecimal} as a big integer value. |
| * @throws ArithmeticException |
| * if rounding is necessary. |
| */ |
| public BigInteger toBigIntegerExact() { |
| if ((scale == 0) || (isZero())) { |
| return getUnscaledValue(); |
| } else if (scale < 0) { |
| return getUnscaledValue().multiply(Multiplication.powerOf10(-(long)scale)); |
| } else {// (scale > 0) |
| BigInteger[] integerAndFraction; |
| // An optimization before do a heavy division |
| if ((scale > approxPrecision()) || (scale > getUnscaledValue().getLowestSetBit())) { |
| throw new ArithmeticException("Rounding necessary"); |
| } |
| integerAndFraction = getUnscaledValue().divideAndRemainder(Multiplication.powerOf10(scale)); |
| if (integerAndFraction[1].signum() != 0) { |
| // It exists a non-zero fractional part |
| throw new ArithmeticException("Rounding necessary"); |
| } |
| return integerAndFraction[0]; |
| } |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as an long value. Any fractional part is |
| * discarded. If the integral part of {@code this} is too big to be |
| * represented as an long, then {@code this % 2<sup>64</sup>} is returned. |
| */ |
| @Override |
| public long longValue() { |
| /* |
| * If scale <= -64 there are at least 64 trailing bits zero in |
| * 10^(-scale). If the scale is positive and very large the long value |
| * could be zero. |
| */ |
| return ((scale <= -64) || (scale > approxPrecision()) ? 0L : toBigInteger().longValue()); |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as a long value if it has no fractional |
| * part and if its value fits to the int range ([-2<sup>63</sup>..2<sup>63</sup>-1]). If |
| * these conditions are not met, an {@code ArithmeticException} is thrown. |
| * |
| * @throws ArithmeticException |
| * if rounding is necessary or the number doesn't fit in a long. |
| */ |
| public long longValueExact() { |
| return valueExact(64); |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as an int value. Any fractional part is |
| * discarded. If the integral part of {@code this} is too big to be |
| * represented as an int, then {@code this % 2<sup>32</sup>} is returned. |
| */ |
| @Override |
| public int intValue() { |
| /* |
| * If scale <= -32 there are at least 32 trailing bits zero in |
| * 10^(-scale). If the scale is positive and very large the long value |
| * could be zero. |
| */ |
| return ((scale <= -32) || (scale > approxPrecision()) ? 0 : toBigInteger().intValue()); |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as a int value if it has no fractional |
| * part and if its value fits to the int range ([-2<sup>31</sup>..2<sup>31</sup>-1]). If |
| * these conditions are not met, an {@code ArithmeticException} is thrown. |
| * |
| * @throws ArithmeticException |
| * if rounding is necessary or the number doesn't fit in an int. |
| */ |
| public int intValueExact() { |
| return (int) valueExact(32); |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as a short value if it has no fractional |
| * part and if its value fits to the short range ([-2<sup>15</sup>..2<sup>15</sup>-1]). If |
| * these conditions are not met, an {@code ArithmeticException} is thrown. |
| * |
| * @throws ArithmeticException |
| * if rounding is necessary of the number doesn't fit in a short. |
| */ |
| public short shortValueExact() { |
| return (short) valueExact(16); |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as a byte value if it has no fractional |
| * part and if its value fits to the byte range ([-128..127]). If these |
| * conditions are not met, an {@code ArithmeticException} is thrown. |
| * |
| * @throws ArithmeticException |
| * if rounding is necessary or the number doesn't fit in a byte. |
| */ |
| public byte byteValueExact() { |
| return (byte) valueExact(8); |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as a float value. If {@code this} is too |
| * big to be represented as an float, then {@code Float.POSITIVE_INFINITY} |
| * or {@code Float.NEGATIVE_INFINITY} is returned. |
| * <p> |
| * Note, that if the unscaled value has more than 24 significant digits, |
| * then this decimal cannot be represented exactly in a float variable. In |
| * this case the result is rounded. |
| * <p> |
| * For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be |
| * represented exactly as a float, and thus {@code x1.equals(new |
| * BigDecimal(x1.floatValue())} returns {@code false} for this case. |
| * <p> |
| * Similarly, if the instance {@code new BigDecimal(16777217)} is converted |
| * to a float, the result is {@code 1.6777216E}7. |
| * |
| * @return this {@code BigDecimal} as a float value. |
| */ |
| @Override |
| public float floatValue() { |
| /* A similar code like in doubleValue() could be repeated here, |
| * but this simple implementation is quite efficient. */ |
| float floatResult = signum(); |
| long powerOfTwo = this.bitLength - (long)(scale / LOG10_2); |
| if ((powerOfTwo < -149) || (floatResult == 0.0f)) { |
| // Cases which 'this' is very small |
| floatResult *= 0.0f; |
| } else if (powerOfTwo > 129) { |
| // Cases which 'this' is very large |
| floatResult *= Float.POSITIVE_INFINITY; |
| } else { |
| floatResult = (float)doubleValue(); |
| } |
| return floatResult; |
| } |
| |
| /** |
| * Returns this {@code BigDecimal} as a double value. If {@code this} is too |
| * big to be represented as an float, then {@code Double.POSITIVE_INFINITY} |
| * or {@code Double.NEGATIVE_INFINITY} is returned. |
| * <p> |
| * Note, that if the unscaled value has more than 53 significant digits, |
| * then this decimal cannot be represented exactly in a double variable. In |
| * this case the result is rounded. |
| * <p> |
| * For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be |
| * represented exactly as a double, and thus {@code x1.equals(new |
| * BigDecimal(x1.doubleValue())} returns {@code false} for this case. |
| * <p> |
| * Similarly, if the instance {@code new BigDecimal(9007199254740993L)} is |
| * converted to a double, the result is {@code 9.007199254740992E15}. |
| * <p> |
| * |
| * @return this {@code BigDecimal} as a double value. |
| */ |
| @Override |
| public double doubleValue() { |
| int sign = signum(); |
| int exponent = 1076; // bias + 53 |
| int lowestSetBit; |
| int discardedSize; |
| long powerOfTwo = this.bitLength - (long)(scale / LOG10_2); |
| long bits; // IEEE-754 Standard |
| long tempBits; // for temporal calculations |
| BigInteger mantissa; |
| |
| if ((powerOfTwo < -1074) || (sign == 0)) { |
| // Cases which 'this' is very small |
| return (sign * 0.0d); |
| } else if (powerOfTwo > 1025) { |
| // Cases which 'this' is very large |
| return (sign * Double.POSITIVE_INFINITY); |
| } |
| mantissa = getUnscaledValue().abs(); |
| // Let be: this = [u,s], with s > 0 |
| if (scale <= 0) { |
| // mantissa = abs(u) * 10^s |
| mantissa = mantissa.multiply(Multiplication.powerOf10(-scale)); |
| } else {// (scale > 0) |
| BigInteger quotAndRem[]; |
| BigInteger powerOfTen = Multiplication.powerOf10(scale); |
| int k = 100 - (int)powerOfTwo; |
| int compRem; |
| |
| if (k > 0) { |
| /* Computing (mantissa * 2^k) , where 'k' is a enough big |
| * power of '2' to can divide by 10^s */ |
| mantissa = mantissa.shiftLeft(k); |
| exponent -= k; |
| } |
| // Computing (mantissa * 2^k) / 10^s |
| quotAndRem = mantissa.divideAndRemainder(powerOfTen); |
| // To check if the fractional part >= 0.5 |
| compRem = quotAndRem[1].shiftLeftOneBit().compareTo(powerOfTen); |
| // To add two rounded bits at end of mantissa |
| mantissa = quotAndRem[0].shiftLeft(2).add( |
| BigInteger.valueOf((compRem * (compRem + 3)) / 2 + 1)); |
| exponent -= 2; |
| } |
| lowestSetBit = mantissa.getLowestSetBit(); |
| discardedSize = mantissa.bitLength() - 54; |
| if (discardedSize > 0) {// (n > 54) |
| // mantissa = (abs(u) * 10^s) >> (n - 54) |
| bits = mantissa.shiftRight(discardedSize).longValue(); |
| tempBits = bits; |
| // #bits = 54, to check if the discarded fraction produces a carry |
| if ((((bits & 1) == 1) && (lowestSetBit < discardedSize)) |
| || ((bits & 3) == 3)) { |
| bits += 2; |
| } |
| } else {// (n <= 54) |
| // mantissa = (abs(u) * 10^s) << (54 - n) |
| bits = mantissa.longValue() << -discardedSize; |
| tempBits = bits; |
| // #bits = 54, to check if the discarded fraction produces a carry: |
| if ((bits & 3) == 3) { |
| bits += 2; |
| } |
| } |
| // Testing bit 54 to check if the carry creates a new binary digit |
| if ((bits & 0x40000000000000L) == 0) { |
| // To drop the last bit of mantissa (first discarded) |
| bits >>= 1; |
| // exponent = 2^(s-n+53+bias) |
| exponent += discardedSize; |
| } else {// #bits = 54 |
| bits >>= 2; |
| exponent += discardedSize + 1; |
| } |
| // To test if the 53-bits number fits in 'double' |
| if (exponent > 2046) {// (exponent - bias > 1023) |
| return (sign * Double.POSITIVE_INFINITY); |
| } else if (exponent <= 0) {// (exponent - bias <= -1023) |
| // Denormalized numbers (having exponent == 0) |
| if (exponent < -53) {// exponent - bias < -1076 |
| return (sign * 0.0d); |
| } |
| // -1076 <= exponent - bias <= -1023 |
| // To discard '- exponent + 1' bits |
| bits = tempBits >> 1; |
| tempBits = bits & (-1L >>> (63 + exponent)); |
| bits >>= (-exponent ); |
| // To test if after discard bits, a new carry is generated |
| if (((bits & 3) == 3) || (((bits & 1) == 1) && (tempBits != 0) |
| && (lowestSetBit < discardedSize))) { |
| bits += 1; |
| } |
| exponent = 0; |
| bits >>= 1; |
| } |
| // Construct the 64 double bits: [sign(1), exponent(11), mantissa(52)] |
| bits = (sign & 0x8000000000000000L) | ((long)exponent << 52) |
| | (bits & 0xFFFFFFFFFFFFFL); |
| return Double.longBitsToDouble(bits); |
| } |
| |
| /** |
| * Returns the unit in the last place (ULP) of this {@code BigDecimal} |
| * instance. An ULP is the distance to the nearest big decimal with the same |
| * precision. |
| * |
| * <p>The amount of a rounding error in the evaluation of a floating-point |
| * operation is often expressed in ULPs. An error of 1 ULP is often seen as |
| * a tolerable error. |
| * |
| * <p>For class {@code BigDecimal}, the ULP of a number is simply 10<sup>-scale</sup>. |
| * For example, {@code new BigDecimal(0.1).ulp()} returns {@code 1E-55}. |
| * |
| * @return unit in the last place (ULP) of this {@code BigDecimal} instance. |
| */ |
| public BigDecimal ulp() { |
| return valueOf(1, scale); |
| } |
| |
| /* Private Methods */ |
| |
| /** |
| * It does all rounding work of the public method |
| * {@code round(MathContext)}, performing an inplace rounding |
| * without creating a new object. |
| * |
| * @param mc |
| * the {@code MathContext} for perform the rounding. |
| * @see #round(MathContext) |
| */ |
| private void inplaceRound(MathContext mc) { |
| int mcPrecision = mc.getPrecision(); |
| if (approxPrecision() < mcPrecision || mcPrecision == 0) { |
| return; |
| } |
| int discardedPrecision = precision() - mcPrecision; |
| // If no rounding is necessary it returns immediately |
| if ((discardedPrecision <= 0)) { |
| return; |
| } |
| // When the number is small perform an efficient rounding |
| if (this.bitLength < 64) { |
| smallRound(mc, discardedPrecision); |
| return; |
| } |
| // Getting the integer part and the discarded fraction |
| BigInteger sizeOfFraction = Multiplication.powerOf10(discardedPrecision); |
| BigInteger[] integerAndFraction = getUnscaledValue().divideAndRemainder(sizeOfFraction); |
| long newScale = (long)scale - discardedPrecision; |
| int compRem; |
| BigDecimal tempBD; |
| // If the discarded fraction is non-zero, perform rounding |
| if (integerAndFraction[1].signum() != 0) { |
| // To check if the discarded fraction >= 0.5 |
| compRem = (integerAndFraction[1].abs().shiftLeftOneBit().compareTo(sizeOfFraction)); |
| // To look if there is a carry |
| compRem = roundingBehavior( integerAndFraction[0].testBit(0) ? 1 : 0, |
| integerAndFraction[1].signum() * (5 + compRem), |
| mc.getRoundingMode()); |
| if (compRem != 0) { |
| integerAndFraction[0] = integerAndFraction[0].add(BigInteger.valueOf(compRem)); |
| } |
| tempBD = new BigDecimal(integerAndFraction[0]); |
| // If after to add the increment the precision changed, we normalize the size |
| if (tempBD.precision() > mcPrecision) { |
| integerAndFraction[0] = integerAndFraction[0].divide(BigInteger.TEN); |
| newScale--; |
| } |
| } |
| // To update all internal fields |
| scale = safeLongToInt(newScale); |
| precision = mcPrecision; |
| setUnscaledValue(integerAndFraction[0]); |
| } |
| |
| /** |
| * Returns -1, 0, and 1 if {@code value1 < value2}, {@code value1 == value2}, |
| * and {@code value1 > value2}, respectively, when comparing without regard |
| * to the values' sign. |
| * |
| * <p>Note that this implementation deals correctly with Long.MIN_VALUE, |
| * whose absolute magnitude is larger than any other {@code long} value. |
| */ |
| private static int compareAbsoluteValues(long value1, long value2) { |
| // Map long values to the range -1 .. Long.MAX_VALUE so that comparison |
| // of absolute magnitude can be done using regular long arithmetics. |
| // This deals correctly with Long.MIN_VALUE, whose absolute magnitude |
| // is larger than any other long value, and which is mapped to |
| // Long.MAX_VALUE here. |
| // Values that only differ by sign get mapped to the same value, for |
| // example both +3 and -3 get mapped to +2. |
| value1 = Math.abs(value1) - 1; |
| value2 = Math.abs(value2) - 1; |
| // Unlike Long.compare(), we guarantee to return specifically -1 and +1 |
| return value1 > value2 ? 1 : (value1 < value2 ? -1 : 0); |
| } |
| |
| /** |
| * Compares {@code n} against {@code 0.5 * d} in absolute terms (ignoring sign) |
| * and with arithmetics that are safe against overflow or loss of precision. |
| * Returns -1 if {@code n} is less than {@code 0.5 * d}, 0 if {@code n == 0.5 * d}, |
| * or +1 if {@code n > 0.5 * d} when comparing the absolute values under such |
| * arithmetics. |
| */ |
| private static int compareForRounding(long n, long d) { |
| long halfD = d / 2; // rounds towards 0 |
| if (n == halfD || n == -halfD) { |
| // In absolute terms: Because n == halfD, we know that 2 * n + lsb == d |
| // for some lsb value 0 or 1. This means that n == d/2 (result 0) if |
| // lsb is 0, or n < d/2 (result -1) if lsb is 1. In either case, the |
| // result is -lsb. |
| // Since we're calculating in absolute terms, we need the absolute lsb |
| // (d & 1) as opposed to the signed lsb (d % 2) which would be -1 for |
| // negative odd values of d. |
| int lsb = (int) d & 1; |
| return -lsb; // returns 0 or -1 |
| } else { |
| // In absolute terms, either 2 * n + 1 < d (in the case of n < halfD), |
| // or 2 * n > d (in the case of n > halfD). |
| // In either case, comparing n against halfD gets the right result |
| // -1 or +1, respectively. |
| return compareAbsoluteValues(n, halfD); |
| } |
| } |
| |
| /** |
| * This method implements an efficient rounding for numbers which unscaled |
| * value fits in the type {@code long}. |
| * |
| * @param mc |
| * the context to use |
| * @param discardedPrecision |
| * the number of decimal digits that are discarded |
| * @see #round(MathContext) |
| */ |
| private void smallRound(MathContext mc, int discardedPrecision) { |
| long sizeOfFraction = MathUtils.LONG_POWERS_OF_TEN[discardedPrecision]; |
| long newScale = (long)scale - discardedPrecision; |
| long unscaledVal = smallValue; |
| // Getting the integer part and the discarded fraction |
| long integer = unscaledVal / sizeOfFraction; |
| long fraction = unscaledVal % sizeOfFraction; |
| int compRem; |
| // If the discarded fraction is non-zero perform rounding |
| if (fraction != 0) { |
| // To check if the discarded fraction >= 0.5 |
| compRem = compareForRounding(fraction, sizeOfFraction); |
| // To look if there is a carry |
| integer += roundingBehavior( ((int)integer) & 1, |
| Long.signum(fraction) * (5 + compRem), |
| mc.getRoundingMode()); |
| // If after to add the increment the precision changed, we normalize the size |
| if (Math.log10(Math.abs(integer)) >= mc.getPrecision()) { |
| integer /= 10; |
| newScale--; |
| } |
| } |
| // To update all internal fields |
| scale = safeLongToInt(newScale); |
| precision = mc.getPrecision(); |
| smallValue = integer; |
| bitLength = bitLength(integer); |
| intVal = null; |
| } |
| |
| /** |
| * Return an increment that can be -1,0 or 1, depending of |
| * {@code roundingMode}. |
| * |
| * @param parityBit |
| * can be 0 or 1, it's only used in the case |
| * {@code HALF_EVEN} |
| * @param fraction |
| * the mantissa to be analyzed |
| * @param roundingMode |
| * the type of rounding |
| * @return the carry propagated after rounding |
| */ |
| private static int roundingBehavior(int parityBit, int fraction, RoundingMode roundingMode) { |
| int increment = 0; // the carry after rounding |
| |
| switch (roundingMode) { |
| case UNNECESSARY: |
| if (fraction != 0) { |
| throw new ArithmeticException("Rounding necessary"); |
| } |
| break; |
| case UP: |
| increment = Integer.signum(fraction); |
| break; |
| case DOWN: |
| break; |
| case CEILING: |
| increment = Math.max(Integer.signum(fraction), 0); |
| break; |
| case FLOOR: |
| increment = Math.min(Integer.signum(fraction), 0); |
| break; |
| case HALF_UP: |
| if (Math.abs(fraction) >= 5) { |
| increment = Integer.signum(fraction); |
| } |
| break; |
| case HALF_DOWN: |
| if (Math.abs(fraction) > 5) { |
| increment = Integer.signum(fraction); |
| } |
| break; |
| case HALF_EVEN: |
| if (Math.abs(fraction) + parityBit > 5) { |
| increment = Integer.signum(fraction); |
| } |
| break; |
| } |
| return increment; |
| } |
| |
| /** |
| * If {@code intVal} has a fractional part throws an exception, |
| * otherwise it counts the number of bits of value and checks if it's out of |
| * the range of the primitive type. If the number fits in the primitive type |
| * returns this number as {@code long}, otherwise throws an |
| * exception. |
| * |
| * @param bitLengthOfType |
| * number of bits of the type whose value will be calculated |
| * exactly |
| * @return the exact value of the integer part of {@code BigDecimal} |
| * when is possible |
| * @throws ArithmeticException when rounding is necessary or the |
| * number don't fit in the primitive type |
| */ |
| private long valueExact(int bitLengthOfType) { |
| BigInteger bigInteger = toBigIntegerExact(); |
| |
| if (bigInteger.bitLength() < bitLengthOfType) { |
| // It fits in the primitive type |
| return bigInteger.longValue(); |
| } |
| throw new ArithmeticException("Rounding necessary"); |
| } |
| |
| /** |
| * If the precision already was calculated it returns that value, otherwise |
| * it calculates a very good approximation efficiently . Note that this |
| * value will be {@code precision()} or {@code precision()-1} |
| * in the worst case. |
| * |
| * @return an approximation of {@code precision()} value |
| */ |
| private int approxPrecision() { |
| return precision > 0 |
| ? precision |
| : (int) ((this.bitLength - 1) * LOG10_2) + 1; |
| } |
| |
| private static int safeLongToInt(long longValue) { |
| if (longValue < Integer.MIN_VALUE || longValue > Integer.MAX_VALUE) { |
| throw new ArithmeticException("Out of int range: " + longValue); |
| } |
| return (int) longValue; |
| } |
| |
| /** |
| * It returns the value 0 with the most approximated scale of type |
| * {@code int}. if {@code longScale > Integer.MAX_VALUE} the |
| * scale will be {@code Integer.MAX_VALUE}; if |
| * {@code longScale < Integer.MIN_VALUE} the scale will be |
| * {@code Integer.MIN_VALUE}; otherwise {@code longScale} is |
| * casted to the type {@code int}. |
| * |
| * @param longScale |
| * the scale to which the value 0 will be scaled. |
| * @return the value 0 scaled by the closer scale of type {@code int}. |
| * @see #scale |
| */ |
| private static BigDecimal zeroScaledBy(long longScale) { |
| if (longScale == (int) longScale) { |
| return valueOf(0,(int)longScale); |
| } |
| if (longScale >= 0) { |
| return new BigDecimal( 0, Integer.MAX_VALUE); |
| } |
| return new BigDecimal( 0, Integer.MIN_VALUE); |
| } |
| |
| /** |
| * Assigns all transient fields upon deserialization of a |
| * {@code BigDecimal} instance (bitLength and smallValue). The transient |
| * field precision is assigned lazily. |
| */ |
| private void readObject(ObjectInputStream in) throws IOException, |
| ClassNotFoundException { |
| in.defaultReadObject(); |
| |
| this.bitLength = intVal.bitLength(); |
| if (this.bitLength < 64) { |
| this.smallValue = intVal.longValue(); |
| } |
| } |
| |
| /** |
| * Prepares this {@code BigDecimal} for serialization, i.e. the |
| * non-transient field {@code intVal} is assigned. |
| */ |
| private void writeObject(ObjectOutputStream out) throws IOException { |
| getUnscaledValue(); |
| out.defaultWriteObject(); |
| } |
| |
| private BigInteger getUnscaledValue() { |
| if(intVal == null) { |
| intVal = BigInteger.valueOf(smallValue); |
| } |
| return intVal; |
| } |
| |
| private void setUnscaledValue(BigInteger unscaledValue) { |
| this.intVal = unscaledValue; |
| this.bitLength = unscaledValue.bitLength(); |
| if(this.bitLength < 64) { |
| this.smallValue = unscaledValue.longValue(); |
| } |
| } |
| |
| private static int bitLength(long smallValue) { |
| if(smallValue < 0) { |
| smallValue = ~smallValue; |
| } |
| return 64 - Long.numberOfLeadingZeros(smallValue); |
| } |
| |
| private static int bitLength(int smallValue) { |
| if(smallValue < 0) { |
| smallValue = ~smallValue; |
| } |
| return 32 - Integer.numberOfLeadingZeros(smallValue); |
| } |
| |
| } |