// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.impl.number;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.text.FieldPosition;

import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.impl.Utility;
import com.ibm.icu.impl.number.Modifier.Signum;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.text.PluralRules.Operand;
import com.ibm.icu.text.UFieldPosition;

/**
 * Represents numbers and digit display properties using Binary Coded Decimal (BCD).
 *
 * @implements {@link DecimalQuantity}
 */
public abstract class DecimalQuantity_AbstractBCD implements DecimalQuantity {

    /**
     * The power of ten corresponding to the least significant digit in the BCD. For example, if this
     * object represents the number "3.14", the BCD will be "0x314" and the scale will be -2.
     *
     * <p>
     * Note that in {@link java.math.BigDecimal}, the scale is defined differently: the number of digits
     * after the decimal place, which is the negative of our definition of scale.
     */
    protected int scale;

    /**
     * The number of digits in the BCD. For example, "1007" has BCD "0x1007" and precision 4. A long
     * cannot represent precisions greater than 16.
     *
     * <p>
     * This value must be re-calculated whenever the value in bcd changes by using
     * {@link #computePrecisionAndCompact()}.
     */
    protected int precision;

    /**
     * A bitmask of properties relating to the number represented by this object.
     *
     * @see #NEGATIVE_FLAG
     * @see #INFINITY_FLAG
     * @see #NAN_FLAG
     */
    protected byte flags;

    protected static final int NEGATIVE_FLAG = 1;
    protected static final int INFINITY_FLAG = 2;
    protected static final int NAN_FLAG = 4;

    // The following three fields relate to the double-to-ascii fast path algorithm.
    // When a double is given to DecimalQuantityBCD, it is converted to using a fast algorithm. The
    // fast algorithm guarantees correctness to only the first ~12 digits of the double. The process
    // of rounding the number ensures that the converted digits are correct, falling back to a slow-
    // path algorithm if required. Therefore, if a DecimalQuantity is constructed from a double, it
    // is *required* that roundToMagnitude(), roundToIncrement(), or roundToInfinity() is called. If
    // you don't round, assertions will fail in certain other methods if you try calling them.

    /**
     * The original number provided by the user and which is represented in BCD. Used when we need to
     * re-compute the BCD for an exact double representation.
     */
    protected double origDouble;

    /**
     * The change in magnitude relative to the original double. Used when we need to re-compute the BCD
     * for an exact double representation.
     */
    protected int origDelta;

    /**
     * Whether the value in the BCD comes from the double fast path without having been rounded to ensure
     * correctness
     */
    protected boolean isApproximate;

    // Positions to keep track of leading and trailing zeros.
    // lReqPos is the magnitude of the first required leading zero.
    // rReqPos is the magnitude of the last required trailing zero.
    protected int lReqPos = 0;
    protected int rReqPos = 0;

    /**
     * The value of the (suppressed) exponent after the number has been put into
     * a notation with exponents (ex: compact, scientific).
     */
    protected int exponent = 0;

    @Override
    public void copyFrom(DecimalQuantity _other) {
        copyBcdFrom(_other);
        DecimalQuantity_AbstractBCD other = (DecimalQuantity_AbstractBCD) _other;
        lReqPos = other.lReqPos;
        rReqPos = other.rReqPos;
        scale = other.scale;
        precision = other.precision;
        flags = other.flags;
        origDouble = other.origDouble;
        origDelta = other.origDelta;
        isApproximate = other.isApproximate;
        exponent = other.exponent;
    }

    public DecimalQuantity_AbstractBCD clear() {
        lReqPos = 0;
        rReqPos = 0;
        flags = 0;
        setBcdToZero(); // sets scale, precision, hasDouble, origDouble, origDelta, exponent, and BCD data
        return this;
    }

    @Override
    public void setMinInteger(int minInt) {
        // Validation should happen outside of DecimalQuantity, e.g., in the Rounder class.
        assert minInt >= 0;

        // Special behavior: do not set minInt to be less than what is already set.
        // This is so significant digits rounding can set the integer length.
        if (minInt < lReqPos) {
            minInt = lReqPos;
        }

        // Save values into internal state
        lReqPos = minInt;
    }

    @Override
    public void setMinFraction(int minFrac) {
        // Validation should happen outside of DecimalQuantity, e.g., in the Rounder class.
        assert minFrac >= 0;

        // Save values into internal state
        // Negation is safe for minFrac/maxFrac because -Integer.MAX_VALUE > Integer.MIN_VALUE
        rReqPos = -minFrac;
    }

    @Override
    public void applyMaxInteger(int maxInt) {
        // Validation should happen outside of DecimalQuantity, e.g., in the Precision class.
        assert maxInt >= 0;

        if (precision == 0) {
            return;
        }

        if (maxInt <= scale) {
            setBcdToZero();
            return;
        }

        int magnitude = getMagnitude();
        if (maxInt <= magnitude) {
            popFromLeft(magnitude - maxInt + 1);
            compact();
        }
    }

    @Override
    public long getPositionFingerprint() {
        long fingerprint = 0;
        fingerprint ^= (lReqPos << 16);
        fingerprint ^= ((long) rReqPos << 32);
        return fingerprint;
    }

    @Override
    public void roundToIncrement(BigDecimal roundingIncrement, MathContext mathContext) {
        // Do not call this method with an increment having only a 1 or a 5 digit!
        // Use a more efficient call to either roundToMagnitude() or roundToNickel().
        // Note: The check, which is somewhat expensive, is performed in an assertion
        // to disable it in production.
        assert roundingIncrement.stripTrailingZeros().precision() != 1
                || roundingIncrement.stripTrailingZeros().unscaledValue().intValue() != 5
                || roundingIncrement.stripTrailingZeros().unscaledValue().intValue() != 1;
        BigDecimal temp = toBigDecimal();
        temp = temp.divide(roundingIncrement, 0, mathContext.getRoundingMode())
                .multiply(roundingIncrement)
                .round(mathContext);
        if (temp.signum() == 0) {
            setBcdToZero(); // keeps negative flag for -0.0
        } else {
            setToBigDecimal(temp);
        }
    }

    @Override
    public void multiplyBy(BigDecimal multiplicand) {
        if (isZeroish()) {
            return;
        }
        BigDecimal temp = toBigDecimal();
        temp = temp.multiply(multiplicand);
        setToBigDecimal(temp);
    }

    @Override
    public void negate() {
      flags ^= NEGATIVE_FLAG;
    }

    @Override
    public int getMagnitude() throws ArithmeticException {
        if (precision == 0) {
            throw new ArithmeticException("Magnitude is not well-defined for zero");
        } else {
            return scale + precision - 1;
        }
    }

    @Override
    public void adjustMagnitude(int delta) {
        if (precision != 0) {
            scale = Utility.addExact(scale, delta);
            origDelta = Utility.addExact(origDelta, delta);
            // Make sure that precision + scale won't overflow, either
            Utility.addExact(scale, precision);
        }
    }

    @Override
    public int getExponent() {
        return exponent;
    }

    @Override
    public void adjustExponent(int delta) {
        exponent = exponent + delta;
    }

    @Override
    public StandardPlural getStandardPlural(PluralRules rules) {
        if (rules == null) {
            // Fail gracefully if the user didn't provide a PluralRules
            return StandardPlural.OTHER;
        } else {
            @SuppressWarnings("deprecation")
            String ruleString = rules.select(this);
            return StandardPlural.orOtherFromString(ruleString);
        }
    }

    @Override
    public double getPluralOperand(Operand operand) {
        // If this assertion fails, you need to call roundToInfinity() or some other rounding method.
        // See the comment at the top of this file explaining the "isApproximate" field.
        assert !isApproximate;

        switch (operand) {
        case i:
            // Invert the negative sign if necessary
            return isNegative() ? -toLong(true) : toLong(true);
        case f:
            return toFractionLong(true);
        case t:
            return toFractionLong(false);
        case v:
            return fractionCount();
        case w:
            return fractionCountWithoutTrailingZeros();
        case e:
            return getExponent();
        default:
            return Math.abs(toDouble());
        }
    }

    @Override
    public void populateUFieldPosition(FieldPosition fp) {
        if (fp instanceof UFieldPosition) {
            ((UFieldPosition) fp).setFractionDigits((int) getPluralOperand(Operand.v),
                    (long) getPluralOperand(Operand.f));
        }
    }

    @Override
    public int getUpperDisplayMagnitude() {
        // If this assertion fails, you need to call roundToInfinity() or some other rounding method.
        // See the comment at the top of this file explaining the "isApproximate" field.
        assert !isApproximate;

        int magnitude = scale + precision;
        int result = (lReqPos > magnitude) ? lReqPos : magnitude;
        return result - 1;
    }

    @Override
    public int getLowerDisplayMagnitude() {
        // If this assertion fails, you need to call roundToInfinity() or some other rounding method.
        // See the comment at the top of this file explaining the "isApproximate" field.
        assert !isApproximate;

        int magnitude = scale;
        int result = (rReqPos < magnitude) ? rReqPos : magnitude;
        return result;
    }

    @Override
    public byte getDigit(int magnitude) {
        // If this assertion fails, you need to call roundToInfinity() or some other rounding method.
        // See the comment at the top of this file explaining the "isApproximate" field.
        assert !isApproximate;

        return getDigitPos(magnitude - scale);
    }

    private int fractionCount() {
        return Math.max(0, -getLowerDisplayMagnitude() - exponent);
    }

    private int fractionCountWithoutTrailingZeros() {
        return Math.max(-scale - exponent, 0);
    }

    @Override
    public boolean isNegative() {
        return (flags & NEGATIVE_FLAG) != 0;
    }

    @Override
    public Signum signum() {
        boolean isZero = (isZeroish() && !isInfinite());
        boolean isNeg = isNegative();
        if (isZero && isNeg) {
            return Signum.NEG_ZERO;
        } else if (isZero) {
            return Signum.POS_ZERO;
        } else if (isNeg) {
            return Signum.NEG;
        } else {
            return Signum.POS;
        }
    }

    @Override
    public boolean isInfinite() {
        return (flags & INFINITY_FLAG) != 0;
    }

    @Override
    public boolean isNaN() {
        return (flags & NAN_FLAG) != 0;
    }

    @Override
    public boolean isZeroish() {
        return precision == 0;
    }

    public void setToInt(int n) {
        setBcdToZero();
        flags = 0;
        if (n < 0) {
            flags |= NEGATIVE_FLAG;
            n = -n;
        }
        if (n != 0) {
            _setToInt(n);
            compact();
        }
    }

    private void _setToInt(int n) {
        if (n == Integer.MIN_VALUE) {
            readLongToBcd(-(long) n);
        } else {
            readIntToBcd(n);
        }
    }

    public void setToLong(long n) {
        setBcdToZero();
        flags = 0;
        if (n < 0) {
            flags |= NEGATIVE_FLAG;
            n = -n;
        }
        if (n != 0) {
            _setToLong(n);
            compact();
        }
    }

    private void _setToLong(long n) {
        if (n == Long.MIN_VALUE) {
            readBigIntegerToBcd(BigInteger.valueOf(n).negate());
        } else if (n <= Integer.MAX_VALUE) {
            readIntToBcd((int) n);
        } else {
            readLongToBcd(n);
        }
    }

    public void setToBigInteger(BigInteger n) {
        setBcdToZero();
        flags = 0;
        if (n.signum() == -1) {
            flags |= NEGATIVE_FLAG;
            n = n.negate();
        }
        if (n.signum() != 0) {
            _setToBigInteger(n);
            compact();
        }
    }

    private void _setToBigInteger(BigInteger n) {
        if (n.bitLength() < 32) {
            readIntToBcd(n.intValue());
        } else if (n.bitLength() < 64) {
            readLongToBcd(n.longValue());
        } else {
            readBigIntegerToBcd(n);
        }
    }

    /**
     * Sets the internal BCD state to represent the value in the given double.
     *
     * @param n
     *            The value to consume.
     */
    public void setToDouble(double n) {
        setBcdToZero();
        flags = 0;
        // The sign bit is the top bit in both double and long, so we can
        // get the long bits for the double and compare it to zero to check
        // the sign of the double.
        if (Double.doubleToRawLongBits(n) < 0) {
            flags |= NEGATIVE_FLAG;
            n = -n;
        }
        if (Double.isNaN(n)) {
            flags |= NAN_FLAG;
        } else if (Double.isInfinite(n)) {
            flags |= INFINITY_FLAG;
        } else if (n != 0) {
            _setToDoubleFast(n);
            compact();
        }
    }

    private static final double[] DOUBLE_MULTIPLIERS = {
            1e0,
            1e1,
            1e2,
            1e3,
            1e4,
            1e5,
            1e6,
            1e7,
            1e8,
            1e9,
            1e10,
            1e11,
            1e12,
            1e13,
            1e14,
            1e15,
            1e16,
            1e17,
            1e18,
            1e19,
            1e20,
            1e21 };

    /**
     * Uses double multiplication and division to get the number into integer space before converting to
     * digits. Since double arithmetic is inexact, the resulting digits may not be accurate.
     */
    private void _setToDoubleFast(double n) {
        isApproximate = true;
        origDouble = n;
        origDelta = 0;

        // NOTE: Unlike ICU4C, doubles are always IEEE 754 doubles.
        long ieeeBits = Double.doubleToLongBits(n);
        int exponent = (int) ((ieeeBits & 0x7ff0000000000000L) >> 52) - 0x3ff;

        // Not all integers can be represented exactly for exponent > 52
        if (exponent <= 52 && (long) n == n) {
            _setToLong((long) n);
            return;
        }

        if (exponent == -1023 || exponent == 1024) {
            // The extreme values of exponent are special; use slow path.
            convertToAccurateDouble();
            return;
        }

        // 3.3219... is log2(10)
        int fracLength = (int) ((52 - exponent) / 3.32192809488736234787031942948939017586);
        if (fracLength >= 0) {
            int i = fracLength;
            // 1e22 is the largest exact double.
            for (; i >= 22; i -= 22)
                n *= 1e22;
            n *= DOUBLE_MULTIPLIERS[i];
        } else {
            int i = fracLength;
            // 1e22 is the largest exact double.
            for (; i <= -22; i += 22)
                n /= 1e22;
            n /= DOUBLE_MULTIPLIERS[-i];
        }
        long result = Math.round(n);
        if (result != 0) {
            _setToLong(result);
            scale -= fracLength;
        }
    }

    /**
     * Uses Double.toString() to obtain an exact accurate representation of the double, overwriting it
     * into the BCD. This method can be called at any point after {@link #_setToDoubleFast} while
     * {@link #isApproximate} is still true.
     */
    private void convertToAccurateDouble() {
        double n = origDouble;
        assert n != 0;
        int delta = origDelta;
        setBcdToZero();

        // Call the slow oracle function (Double.toString in Java, sprintf in C++).
        String dstr = Double.toString(n);

        if (dstr.indexOf('E') != -1) {
            // Case 1: Exponential notation.
            assert dstr.indexOf('.') == 1;
            int expPos = dstr.indexOf('E');
            _setToLong(Long.parseLong(dstr.charAt(0) + dstr.substring(2, expPos)));
            scale += Integer.parseInt(dstr.substring(expPos + 1)) - (expPos - 1) + 1;
        } else if (dstr.charAt(0) == '0') {
            // Case 2: Fraction-only number.
            assert dstr.indexOf('.') == 1;
            _setToLong(Long.parseLong(dstr.substring(2)));
            scale += 2 - dstr.length();
        } else if (dstr.charAt(dstr.length() - 1) == '0') {
            // Case 3: Integer-only number.
            // Note: this path should not normally happen, because integer-only numbers are captured
            // before the approximate double logic is performed.
            assert dstr.indexOf('.') == dstr.length() - 2;
            assert dstr.length() - 2 <= 18;
            _setToLong(Long.parseLong(dstr.substring(0, dstr.length() - 2)));
            // no need to adjust scale
        } else {
            // Case 4: Number with both a fraction and an integer.
            int decimalPos = dstr.indexOf('.');
            _setToLong(Long.parseLong(dstr.substring(0, decimalPos) + dstr.substring(decimalPos + 1)));
            scale += decimalPos - dstr.length() + 1;
        }

        scale += delta;
        compact();
        explicitExactDouble = true;
    }

    /**
     * Whether this {@link DecimalQuantity_DualStorageBCD} has been explicitly converted to an exact
     * double. true if backed by a double that was explicitly converted via convertToAccurateDouble;
     * false otherwise. Used for testing.
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public boolean explicitExactDouble = false;

    /**
     * Sets the internal BCD state to represent the value in the given BigDecimal.
     *
     * @param n
     *            The value to consume.
     */
    @Override
    public void setToBigDecimal(BigDecimal n) {
        setBcdToZero();
        flags = 0;
        if (n.signum() == -1) {
            flags |= NEGATIVE_FLAG;
            n = n.negate();
        }
        if (n.signum() != 0) {
            _setToBigDecimal(n);
            compact();
        }
    }

    private void _setToBigDecimal(BigDecimal n) {
        int fracLength = n.scale();
        n = n.scaleByPowerOfTen(fracLength);
        BigInteger bi = n.toBigInteger();
        _setToBigInteger(bi);
        scale -= fracLength;
    }

    /**
     * Returns a long approximating the internal BCD. A long can only represent the integral part of the
     * number.  Note: this method incorporates the value of {@code exponent}
     * (for cases such as compact notation) to return the proper long value
     * represented by the result.
     *
     * @param truncateIfOverflow if false and the number does NOT fit, fails with an assertion error.
     * @return A 64-bit integer representation of the internal BCD.
     */
    public long toLong(boolean truncateIfOverflow) {
        // NOTE: Call sites should be guarded by fitsInLong(), like this:
        // if (dq.fitsInLong()) { /* use dq.toLong() */ } else { /* use some fallback */ }
        // Fallback behavior upon truncateIfOverflow is to truncate at 17 digits.
        assert(truncateIfOverflow || fitsInLong());
        long result = 0L;
        int upperMagnitude = exponent + scale + precision - 1;
        if (truncateIfOverflow) {
            upperMagnitude = Math.min(upperMagnitude, 17);
        }
        for (int magnitude = upperMagnitude; magnitude >= 0; magnitude--) {
            result = result * 10 + getDigitPos(magnitude - scale - exponent);
        }
        if (isNegative()) {
            result = -result;
        }
        return result;
    }

    /**
     * This returns a long representing the fraction digits of the number, as required by PluralRules.
     * For example, if we represent the number "1.20" (including optional and required digits), then this
     * function returns "20" if includeTrailingZeros is true or "2" if false.
     * Note: this method incorporates the value of {@code exponent}
     * (for cases such as compact notation) to return the proper long value
     * represented by the result.
     */
    public long toFractionLong(boolean includeTrailingZeros) {
        long result = 0L;
        int magnitude = -1 - exponent;
        int lowerMagnitude = scale;
        if (includeTrailingZeros) {
            lowerMagnitude = Math.min(lowerMagnitude, rReqPos);
        }
        // NOTE: Java has only signed longs, so we check result <= 1e17 instead of 1e18
        for (; magnitude >= lowerMagnitude && result <= 1e17; magnitude--) {
            result = result * 10 + getDigitPos(magnitude - scale);
        }
        // Remove trailing zeros; this can happen during integer overflow cases.
        if (!includeTrailingZeros) {
            while (result > 0 && (result % 10) == 0) {
                result /= 10;
            }
        }
        return result;
    }

    static final byte[] INT64_BCD = { 9, 2, 2, 3, 3, 7, 2, 0, 3, 6, 8, 5, 4, 7, 7, 5, 8, 0, 8 };

    /**
     * Returns whether or not a Long can fully represent the value stored in this DecimalQuantity.
     */
    public boolean fitsInLong() {
        if (isInfinite() || isNaN()) {
            return false;
        }
        if (isZeroish()) {
            return true;
        }
        if (exponent + scale < 0) {
            return false;
        }
        int magnitude = getMagnitude();
        if (magnitude < 18) {
            return true;
        }
        if (magnitude > 18) {
            return false;
        }
        // Hard case: the magnitude is 10^18.
        // The largest int64 is: 9,223,372,036,854,775,807
        for (int p = 0; p < precision; p++) {
            byte digit = getDigit(18 - p);
            if (digit < INT64_BCD[p]) {
                return true;
            } else if (digit > INT64_BCD[p]) {
                return false;
            }
        }
        // Exactly equal to max long plus one.
        return isNegative();
    }

    /**
     * Returns a double approximating the internal BCD. The double may not retain all of the information
     * encoded in the BCD if the BCD represents a number out of range of a double.
     *
     * @return A double representation of the internal BCD.
     */
    @Override
    public double toDouble() {
        // If this assertion fails, you need to call roundToInfinity() or some other rounding method.
        // See the comment at the top of this file explaining the "isApproximate" field.
        assert !isApproximate;

        if (isNaN()) {
            return Double.NaN;
        } else if (isInfinite()) {
            return isNegative() ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
        }

        StringBuilder sb = new StringBuilder();
        toScientificString(sb);
        return Double.valueOf(sb.toString());
    }

    @Override
    public BigDecimal toBigDecimal() {
        if (isApproximate) {
            // Converting to a BigDecimal requires Double.toString().
            convertToAccurateDouble();
        }
        return bcdToBigDecimal();
    }

    private static int safeSubtract(int a, int b) {
        int diff = a - b;
        if (b < 0 && diff < a)
            return Integer.MAX_VALUE;
        if (b > 0 && diff > a)
            return Integer.MIN_VALUE;
        return diff;
    }

    private static final int SECTION_LOWER_EDGE = -1;
    private static final int SECTION_UPPER_EDGE = -2;

    /** Removes all fraction digits. */
    public void truncate() {
        if (scale < 0) {
            shiftRight(-scale);
            scale = 0;
            compact();
        }
    }

    @Override
    public void roundToNickel(int magnitude, MathContext mathContext) {
        roundToMagnitude(magnitude, mathContext, true);
    }

    @Override
    public void roundToMagnitude(int magnitude, MathContext mathContext) {
        roundToMagnitude(magnitude, mathContext, false);
    }

    private void roundToMagnitude(int magnitude, MathContext mathContext, boolean nickel) {
        // The position in the BCD at which rounding will be performed; digits to the right of position
        // will be rounded away.
        int position = safeSubtract(magnitude, scale);

        // Enforce the number of digits required by the MathContext.
        int _mcPrecision = mathContext.getPrecision();
        if (_mcPrecision > 0 && precision - _mcPrecision > position) {
            position = precision - _mcPrecision;
        }

        // "trailing" = least significant digit to the left of rounding
        byte trailingDigit = getDigitPos(position);

        if (position <= 0 && !isApproximate && (!nickel || trailingDigit == 0 || trailingDigit == 5)) {
            // All digits are to the left of the rounding magnitude.
        } else if (precision == 0) {
            // No rounding for zero.
        } else {
            // Perform rounding logic.
            // "leading" = most significant digit to the right of rounding
            byte leadingDigit = getDigitPos(safeSubtract(position, 1));

            // Compute which section of the number we are in.
            // EDGE means we are at the bottom or top edge, like 1.000 or 1.999 (used by doubles)
            // LOWER means we are between the bottom edge and the midpoint, like 1.391
            // MIDPOINT means we are exactly in the middle, like 1.500
            // UPPER means we are between the midpoint and the top edge, like 1.916
            int section;
            if (!isApproximate) {
                if (nickel && trailingDigit != 2 && trailingDigit != 7) {
                    // Nickel rounding, and not at .02x or .07x
                    if (trailingDigit < 2) {
                        // .00, .01 => down to .00
                        section = RoundingUtils.SECTION_LOWER;
                    } else if (trailingDigit < 5) {
                        // .03, .04 => up to .05
                        section = RoundingUtils.SECTION_UPPER;
                    } else if (trailingDigit < 7) {
                        // .05, .06 => down to .05
                        section = RoundingUtils.SECTION_LOWER;
                    } else {
                        // .08, .09 => up to .10
                        section = RoundingUtils.SECTION_UPPER;
                    }
                } else if (leadingDigit < 5) {
                    // Includes nickel rounding .020-.024 and .070-.074
                    section = RoundingUtils.SECTION_LOWER;
                } else if (leadingDigit > 5) {
                    // Includes nickel rounding .026-.029 and .076-.079
                    section = RoundingUtils.SECTION_UPPER;
                } else {
                    // Includes nickel rounding .025 and .075
                    section = RoundingUtils.SECTION_MIDPOINT;
                    for (int p = safeSubtract(position, 2); p >= 0; p--) {
                        if (getDigitPos(p) != 0) {
                            section = RoundingUtils.SECTION_UPPER;
                            break;
                        }
                    }
                }
            } else {
                int p = safeSubtract(position, 2);
                int minP = Math.max(0, precision - 14);
                if (leadingDigit == 0 && (!nickel || trailingDigit == 0 || trailingDigit == 5)) {
                    section = SECTION_LOWER_EDGE;
                    for (; p >= minP; p--) {
                        if (getDigitPos(p) != 0) {
                            section = RoundingUtils.SECTION_LOWER;
                            break;
                        }
                    }
                } else if (leadingDigit == 4 && (!nickel || trailingDigit == 2 || trailingDigit == 7)) {
                    section = RoundingUtils.SECTION_MIDPOINT;
                    for (; p >= minP; p--) {
                        if (getDigitPos(p) != 9) {
                            section = RoundingUtils.SECTION_LOWER;
                            break;
                        }
                    }
                } else if (leadingDigit == 5 && (!nickel || trailingDigit == 2 || trailingDigit == 7)) {
                    section = RoundingUtils.SECTION_MIDPOINT;
                    for (; p >= minP; p--) {
                        if (getDigitPos(p) != 0) {
                            section = RoundingUtils.SECTION_UPPER;
                            break;
                        }
                    }
                } else if (leadingDigit == 9 && (!nickel || trailingDigit == 4 || trailingDigit == 9)) {
                    section = SECTION_UPPER_EDGE;
                    for (; p >= minP; p--) {
                        if (getDigitPos(p) != 9) {
                            section = RoundingUtils.SECTION_UPPER;
                            break;
                        }
                    }
                } else if (nickel && trailingDigit != 2 && trailingDigit != 7) {
                    // Nickel rounding, and not at .02x or .07x
                    if (trailingDigit < 2) {
                        // .00, .01 => down to .00
                        section = RoundingUtils.SECTION_LOWER;
                    } else if (trailingDigit < 5) {
                        // .03, .04 => up to .05
                        section = RoundingUtils.SECTION_UPPER;
                    } else if (trailingDigit < 7) {
                        // .05, .06 => down to .05
                        section = RoundingUtils.SECTION_LOWER;
                    } else {
                        // .08, .09 => up to .10
                        section = RoundingUtils.SECTION_UPPER;
                    }
                } else if (leadingDigit < 5) {
                    // Includes nickel rounding .020-.024 and .070-.074
                    section = RoundingUtils.SECTION_LOWER;
                } else {
                    // Includes nickel rounding .026-.029 and .076-.079
                    section = RoundingUtils.SECTION_UPPER;
                }

                boolean roundsAtMidpoint = RoundingUtils
                        .roundsAtMidpoint(mathContext.getRoundingMode().ordinal());
                if (safeSubtract(position, 1) < precision - 14
                        || (roundsAtMidpoint && section == RoundingUtils.SECTION_MIDPOINT)
                        || (!roundsAtMidpoint && section < 0 /* i.e. at upper or lower edge */)) {
                    // Oops! This means that we have to get the exact representation of the double,
                    // because the zone of uncertainty is along the rounding boundary.
                    convertToAccurateDouble();
                    roundToMagnitude(magnitude, mathContext, nickel); // start over
                    return;
                }

                // Turn off the approximate double flag, since the value is now confirmed to be exact.
                isApproximate = false;
                origDouble = 0.0;
                origDelta = 0;

                if (position <= 0 && (!nickel || trailingDigit == 0 || trailingDigit == 5)) {
                    // All digits are to the left of the rounding magnitude.
                    return;
                }

                // Good to continue rounding.
                if (section == SECTION_LOWER_EDGE)
                    section = RoundingUtils.SECTION_LOWER;
                if (section == SECTION_UPPER_EDGE)
                    section = RoundingUtils.SECTION_UPPER;
            }

            // Nickel rounding "half even" goes to the nearest whole (away from the 5).
            boolean isEven = nickel
                    ? (trailingDigit < 2 || trailingDigit > 7
                            || (trailingDigit == 2 && section != RoundingUtils.SECTION_UPPER)
                            || (trailingDigit == 7 && section == RoundingUtils.SECTION_UPPER))
                    : (trailingDigit % 2) == 0;

            boolean roundDown = RoundingUtils.getRoundingDirection(isEven,
                    isNegative(),
                    section,
                    mathContext.getRoundingMode().ordinal(),
                    this);

            // Perform truncation
            if (position >= precision) {
                setBcdToZero();
                scale = magnitude;
            } else {
                shiftRight(position);
            }

            if (nickel) {
                if (trailingDigit < 5 && roundDown) {
                    setDigitPos(0, (byte) 0);
                    compact();
                    return;
                } else if (trailingDigit >= 5 && !roundDown) {
                    setDigitPos(0, (byte) 9);
                    trailingDigit = 9;
                    // do not return: use the bubbling logic below
                } else {
                    setDigitPos(0, (byte) 5);
                    // compact not necessary: digit at position 0 is nonzero
                    return;
                }
            }

            // Bubble the result to the higher digits
            if (!roundDown) {
                if (trailingDigit == 9) {
                    int bubblePos = 0;
                    // Note: in the long implementation, the most digits BCD can have at this point is
                    // 15, so bubblePos <= 15 and getDigitPos(bubblePos) is safe.
                    for (; getDigitPos(bubblePos) == 9; bubblePos++) {
                    }
                    shiftRight(bubblePos); // shift off the trailing 9s
                }
                byte digit0 = getDigitPos(0);
                assert digit0 != 9;
                setDigitPos(0, (byte) (digit0 + 1));
                precision += 1; // in case an extra digit got added
            }

            compact();
        }
    }

    @Override
    public void roundToInfinity() {
        if (isApproximate) {
            convertToAccurateDouble();
        }
    }

    /**
     * Appends a digit, optionally with one or more leading zeros, to the end of the value represented by
     * this DecimalQuantity.
     *
     * <p>
     * The primary use of this method is to construct numbers during a parsing loop. It allows parsing to
     * take advantage of the digit list infrastructure primarily designed for formatting.
     *
     * @param value
     *            The digit to append.
     * @param leadingZeros
     *            The number of zeros to append before the digit. For example, if the value in this
     *            instance starts as 12.3, and you append a 4 with 1 leading zero, the value becomes
     *            12.304.
     * @param appendAsInteger
     *            If true, increase the magnitude of existing digits to make room for the new digit. If
     *            false, append to the end like a fraction digit. If true, there must not be any fraction
     *            digits already in the number.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public void appendDigit(byte value, int leadingZeros, boolean appendAsInteger) {
        assert leadingZeros >= 0;

        // Zero requires special handling to maintain the invariant that the least-significant digit
        // in the BCD is nonzero.
        if (value == 0) {
            if (appendAsInteger && precision != 0) {
                scale += leadingZeros + 1;
            }
            return;
        }

        // Deal with trailing zeros
        if (scale > 0) {
            leadingZeros += scale;
            if (appendAsInteger) {
                scale = 0;
            }
        }

        // Append digit
        shiftLeft(leadingZeros + 1);
        setDigitPos(0, value);

        // Fix scale if in integer mode
        if (appendAsInteger) {
            scale += leadingZeros + 1;
        }
    }

    @Override
    public String toPlainString() {
        StringBuilder sb = new StringBuilder();
        toPlainString(sb);
        return sb.toString();
    }

    public void toPlainString(StringBuilder result) {
        assert(!isApproximate);
        if (isNegative()) {
            result.append('-');
        }
        if (precision == 0) {
            result.append('0');
            return;
        }

        int upper = scale + precision + exponent - 1;
        int lower = scale + exponent;
        if (upper < lReqPos - 1) {
            upper = lReqPos - 1;
        }
        if (lower > rReqPos) {
            lower = rReqPos;
        }

        int p = upper;
        if (p < 0) {
            result.append('0');
        }
        for (; p >= 0; p--) {
            result.append((char) ('0' + getDigitPos(p - scale - exponent)));
        }
        if (lower < 0) {
            result.append('.');
        }
        for(; p >= lower; p--) {
            result.append((char) ('0' + getDigitPos(p - scale - exponent)));
        }
    }

    public String toScientificString() {
        StringBuilder sb = new StringBuilder();
        toScientificString(sb);
        return sb.toString();
    }

    public void toScientificString(StringBuilder result) {
        assert(!isApproximate);
        if (isNegative()) {
            result.append('-');
        }
        if (precision == 0) {
            result.append("0E+0");
            return;
        }
        // NOTE: It is not safe to add to lOptPos (aka maxInt) or subtract from
        // rOptPos (aka -maxFrac) due to overflow.
        int upperPos = precision - 1;
        int lowerPos = 0;
        int p = upperPos;
        result.append((char) ('0' + getDigitPos(p)));
        if ((--p) >= lowerPos) {
            result.append('.');
            for (; p >= lowerPos; p--) {
                result.append((char) ('0' + getDigitPos(p)));
            }
        }
        result.append('E');
        int _scale = upperPos + scale + exponent;
        if (_scale == Integer.MIN_VALUE) {
            result.append("-2147483648");
            return;
        } else if (_scale < 0) {
            _scale *= -1;
            result.append('-');
        } else {
            result.append('+');
        }
        if (_scale == 0) {
            result.append('0');
        }
        int insertIndex = result.length();
        while (_scale > 0) {
            int quot = _scale / 10;
            int rem = _scale % 10;
            result.insert(insertIndex, (char) ('0' + rem));
            _scale = quot;
        }
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }
        if (other == null) {
            return false;
        }
        if (!(other instanceof DecimalQuantity_AbstractBCD)) {
            return false;
        }
        DecimalQuantity_AbstractBCD _other = (DecimalQuantity_AbstractBCD) other;

        boolean basicEquals =
                scale == _other.scale
                && precision == _other.precision
                && flags == _other.flags
                && lReqPos == _other.lReqPos
                && rReqPos == _other.rReqPos
                && isApproximate == _other.isApproximate;
        if (!basicEquals) {
            return false;
        }

        if (precision == 0) {
            return true;
        } else if (isApproximate) {
            return origDouble == _other.origDouble && origDelta == _other.origDelta;
        } else {
            for (int m = getUpperDisplayMagnitude(); m >= getLowerDisplayMagnitude(); m--) {
                if (getDigit(m) != _other.getDigit(m)) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * Returns a single digit from the BCD list. No internal state is changed by calling this method.
     *
     * @param position
     *            The position of the digit to pop, counted in BCD units from the least significant
     *            digit. If outside the range supported by the implementation, zero is returned.
     * @return The digit at the specified location.
     */
    protected abstract byte getDigitPos(int position);

    /**
     * Sets the digit in the BCD list. This method only sets the digit; it is the caller's responsibility
     * to call {@link #compact} after setting the digit.
     *
     * @param position
     *            The position of the digit to pop, counted in BCD units from the least significant
     *            digit. If outside the range supported by the implementation, an AssertionError is
     *            thrown.
     * @param value
     *            The digit to set at the specified location.
     */
    protected abstract void setDigitPos(int position, byte value);

    /**
     * Adds zeros to the end of the BCD list. This will result in an invalid BCD representation; it is
     * the caller's responsibility to do further manipulation and then call {@link #compact}.
     *
     * @param numDigits
     *            The number of zeros to add.
     */
    protected abstract void shiftLeft(int numDigits);

    /**
     * Removes digits from the end of the BCD list. This may result in an invalid BCD representation; it
     * is the caller's responsibility to follow-up with a call to {@link #compact}.
     *
     * @param numDigits
     *            The number of digits to remove.
     */
    protected abstract void shiftRight(int numDigits);

    /**
     * Directly removes digits from the front of the BCD list.
     * Updates precision.
     *
     * CAUTION: it is the caller's responsibility to call {@link #compact} after this method.
     */
    protected abstract void popFromLeft(int numDigits);

    /**
     * Sets the internal representation to zero. Clears any values stored in scale, precision, hasDouble,
     * origDouble, origDelta, exponent, and BCD data.
     */
    protected abstract void setBcdToZero();

    /**
     * Sets the internal BCD state to represent the value in the given int. The int is guaranteed to be
     * either positive. The internal state is guaranteed to be empty when this method is called.
     *
     * @param n
     *            The value to consume.
     */
    protected abstract void readIntToBcd(int input);

    /**
     * Sets the internal BCD state to represent the value in the given long. The long is guaranteed to be
     * either positive. The internal state is guaranteed to be empty when this method is called.
     *
     * @param n
     *            The value to consume.
     */
    protected abstract void readLongToBcd(long input);

    /**
     * Sets the internal BCD state to represent the value in the given BigInteger. The BigInteger is
     * guaranteed to be positive, and it is guaranteed to be larger than Long.MAX_VALUE. The internal
     * state is guaranteed to be empty when this method is called.
     *
     * @param n
     *            The value to consume.
     */
    protected abstract void readBigIntegerToBcd(BigInteger input);

    /**
     * Returns a BigDecimal encoding the internal BCD value.
     *
     * @return A BigDecimal representation of the internal BCD.
     */
    protected abstract BigDecimal bcdToBigDecimal();

    protected abstract void copyBcdFrom(DecimalQuantity _other);

    /**
     * Removes trailing zeros from the BCD (adjusting the scale as required) and then computes the
     * precision. The precision is the number of digits in the number up through the greatest nonzero
     * digit.
     *
     * <p>
     * This method must always be called when bcd changes in order for assumptions to be correct in
     * methods like {@link #fractionCount()}.
     */
    protected abstract void compact();
}
