/*
 *  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()) {
            return new BigDecimal(BigInteger.ZERO, 0);
        }
        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);
    }

}
