151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *   The original version of this source code and documentation is copyrighted
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * materials are provided under terms of a License Agreement between Taligent
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and Sun. This technology is protected by multiple US and International
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * patents. This notice and attribution to Taligent may not be removed.
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *   Taligent is a registered trademark of Taligent, Inc.
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.text;
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.math.BigDecimal;
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.math.BigInteger;
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.math.RoundingMode;
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Digit List. Private to DecimalFormat.
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Handles the transcoding
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * between numeric values and strings of characters.  Only handles
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * non-negative numbers.  The division of labor between DigitList and
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DecimalFormat is that DigitList handles the radix 10 representation
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * issues; DecimalFormat handles the locale-specific issues such as
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * positive/negative, grouping, decimal point, currency, and so on.
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A DigitList is really a representation of a floating point value.
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * It may be an integer value; we assume that a double has sufficient
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * precision to represent all digits of a long.
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The DigitList representation consists of a string of characters,
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * which are the digits radix 10, from '0' to '9'.  It also has a radix
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10 exponent associated with it.  The value represented by a DigitList
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * object can be computed by mulitplying the fraction f, where 0 <= f < 1,
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * derived by placing all the digits of the list to the right of the
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * decimal point, by 10^exponent.
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see  Locale
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see  Format
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see  NumberFormat
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see  DecimalFormat
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see  ChoiceFormat
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see  MessageFormat
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author       Mark Davis, Alan Liu
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskifinal class DigitList implements Cloneable {
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The maximum number of significant digits in an IEEE 754 double, that
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is, in a Java double.  This must not be increased, or garbage digits
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * will be generated, and should not be decreased, or accuracy will be lost.
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static final int MAX_COUNT = 19; // == Long.toString(Long.MAX_VALUE).length()
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * These data members are intentionally public and can be set directly.
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The value represented is given by placing the decimal point before
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * digits[decimalAt].  If decimalAt is < 0, then leading zeros between
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the decimal point and the first nonzero digit are implied.  If decimalAt
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is > count, then trailing zeros between the digits[count-1] and the
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * decimal point are implied.
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Equivalently, the represented value is given by f * 10^decimalAt.  Here
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * f is a value 0.1 <= f < 1 arrived at by placing the digits in Digits to
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the right of the decimal.
9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * DigitList is normalized, so if it is non-zero, figits[0] is non-zero.  We
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * don't allow denormalized numbers because our exponent is effectively of
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * unlimited magnitude.  The count value contains the number of significant
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * digits present in digits[].
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Zero is represented by any DigitList with count == 0 or with each digits[i]
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for all i <= count == '0'.
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int decimalAt = 0;
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int count = 0;
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public char[] digits = new char[MAX_COUNT];
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private char[] data;
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean isNegative = false;
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return true if the represented number is zero.
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean isZero() {
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i=0; i < count; ++i) {
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (digits[i] != '0') {
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return true;
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the rounding mode
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    void setRoundingMode(RoundingMode r) {
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        roundingMode = r;
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Clears out the digits.
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Use before appending them.
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Typically, you set a series of digits with append, then at the point
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * you hit the decimal point, you set myDigitList.decimalAt = myDigitList.count;
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * then go on appending digits.
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void clear () {
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        decimalAt = 0;
13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        count = 0;
13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Appends a digit to the list, extending the list when necessary.
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void append(char digit) {
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (count == digits.length) {
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char[] data = new char[count + 100];
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(digits, 0, data, 0, count);
14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits = data;
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        digits[count++] = digit;
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Utility routine to get the value of the digit list
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If (count == 0) this throws a NumberFormatException, which
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * mimics Long.parseLong().
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final double getDouble() {
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (count == 0) {
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0.0;
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        StringBuffer temp = getStringBuffer();
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        temp.append('.');
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        temp.append(digits, 0, count);
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        temp.append('E');
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        temp.append(decimalAt);
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return Double.parseDouble(temp.toString());
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Utility routine to get the value of the digit list.
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If (count == 0) this returns 0, unlike Long.parseLong().
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final long getLong() {
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // for now, simple implementation; later, do proper IEEE native stuff
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (count == 0) {
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // We have to check for this, because this is the one NEGATIVE value
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // we represent.  If we tried to just pass the digits off to parseLong,
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // we'd get a parse failure.
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isLongMIN_VALUE()) {
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return Long.MIN_VALUE;
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        StringBuffer temp = getStringBuffer();
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        temp.append(digits, 0, count);
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = count; i < decimalAt; ++i) {
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            temp.append('0');
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return Long.parseLong(temp.toString());
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final BigDecimal getBigDecimal() {
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (count == 0) {
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (decimalAt == 0) {
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return BigDecimal.ZERO;
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return new BigDecimal("0E" + decimalAt);
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski       if (decimalAt == count) {
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski           return new BigDecimal(digits, 0, count);
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski       } else {
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski           return new BigDecimal(digits, 0, count).scaleByPowerOfTen(decimalAt - count);
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski       }
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return true if the number represented by this object can fit into
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * a long.
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param isPositive true if this number should be regarded as positive
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param ignoreNegativeZero true if -0 should be regarded as identical to
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * +0; otherwise they are considered distinct
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true if this number fits into a Java long
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    boolean fitsIntoLong(boolean isPositive, boolean ignoreNegativeZero) {
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Figure out if the result will fit in a long.  We have to
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // first look for nonzero digits after the decimal point;
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // then check the size.  If the digit count is 18 or less, then
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // the value can definitely be represented as a long.  If it is 19
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // then it may be too large.
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Trim trailing zeros.  This does not change the represented value.
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (count > 0 && digits[count - 1] == '0') {
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            --count;
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (count == 0) {
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Positive zero fits into a long, but negative zero can only
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // be represented as a double. - bug 4162852
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return isPositive || ignoreNegativeZero;
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (decimalAt < count || decimalAt > MAX_COUNT) {
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (decimalAt < MAX_COUNT) return true;
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // At this point we have decimalAt == count, and count == MAX_COUNT.
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // The number will overflow if it is larger than 9223372036854775807
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // or smaller than -9223372036854775808.
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i=0; i<count; ++i) {
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char dig = digits[i], max = LONG_MIN_REP[i];
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (dig > max) return false;
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (dig < max) return true;
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // At this point the first count digits match.  If decimalAt is less
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // than count, then the remaining digits are zero, and we return true.
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (count < decimalAt) return true;
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Now we have a representation of Long.MIN_VALUE, without the leading
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // negative sign.  If this represents a positive value, then it does
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // not fit; otherwise it fits.
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return !isPositive;
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the digit list to a representation of the given double value.
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This method supports fixed-point notation.
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param isNegative Boolean value indicating whether the number is negative.
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param source Value to be converted; must not be Inf, -Inf, Nan,
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or a value <= 0.
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param maximumFractionDigits The most fractional digits which should
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * be converted.
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final void set(boolean isNegative, double source, int maximumFractionDigits) {
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        set(isNegative, source, maximumFractionDigits, true);
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the digit list to a representation of the given double value.
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This method supports both fixed-point and exponential notation.
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param isNegative Boolean value indicating whether the number is negative.
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param source Value to be converted; must not be Inf, -Inf, Nan,
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * or a value <= 0.
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param maximumDigits The most fractional or total digits which should
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * be converted.
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param fixedPoint If true, then maximumDigits is the maximum
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * fractional digits to be converted.  If false, total digits.
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    final void set(boolean isNegative, double source, int maximumDigits, boolean fixedPoint) {
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        set(isNegative, Double.toString(source), maximumDigits, fixedPoint);
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Generate a representation of the form DDDDD, DDDDD.DDDDD, or
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * DDDDDE+/-DDDDD.
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    final void set(boolean isNegative, String s, int maximumDigits, boolean fixedPoint) {
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.isNegative = isNegative;
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int len = s.length();
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char[] source = getDataChars(len);
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        s.getChars(0, len, source, 0);
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        decimalAt = -1;
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        count = 0;
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int exponent = 0;
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Number of zeros between decimal point and first non-zero digit after
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // decimal point, for numbers < 1.
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int leadingZerosAfterDecimal = 0;
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean nonZeroDigitSeen = false;
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < len; ) {
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char c = source[i++];
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (c == '.') {
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decimalAt = count;
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (c == 'e' || c == 'E') {
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                exponent = parseInt(source, i, len);
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (!nonZeroDigitSeen) {
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    nonZeroDigitSeen = (c != '0');
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (!nonZeroDigitSeen && decimalAt != -1)
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ++leadingZerosAfterDecimal;
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (nonZeroDigitSeen) {
32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[count++] = c;
32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (decimalAt == -1) {
32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            decimalAt = count;
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (nonZeroDigitSeen) {
33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            decimalAt += exponent - leadingZerosAfterDecimal;
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (fixedPoint) {
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // The negative of the exponent represents the number of leading
33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // zeros between the decimal and the first non-zero digit, for
33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // a value < 0.1 (e.g., for 0.00123, -decimalAt == 2).  If this
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // is more than the maximum fraction digits, then we have an underflow
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // for the printed representation.
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (-decimalAt > maximumDigits) {
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Handle an underflow to zero when we round something like
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // 0.0009 to 2 fractional digits.
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                count = 0;
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else if (-decimalAt == maximumDigits) {
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // If we round 0.0009 to 3 fractional digits, then we have to
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // create a new one digit in the least significant location.
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (shouldRoundUp(0)) {
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    count = 1;
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ++decimalAt;
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    digits[0] = '1';
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    count = 0;
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return;
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // else fall through
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Eliminate trailing zeros.
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (count > 1 && digits[count - 1] == '0') {
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            --count;
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Eliminate digits beyond maximum digits to be displayed.
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Round up if appropriate.
36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits);
36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Round the representation to the given number of digits.
37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param maximumDigits The maximum number of digits to be shown.
37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Upon return, count will be less than or equal to maximumDigits.
37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
37651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final void round(int maximumDigits) {
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Eliminate digits beyond maximum digits to be displayed.
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // Round up if appropriate.
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (maximumDigits >= 0 && maximumDigits < count) {
38051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (shouldRoundUp(maximumDigits)) {
38151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Rounding up involved incrementing digits from LSD to MSD.
38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // In most cases this is simple, but in a worst case situation
38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // (9999..99) we have to adjust the decimalAt value.
38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (;;) {
38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    --maximumDigits;
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (maximumDigits < 0) {
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // We have all 9's, so we increment to a single digit
38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // of one and adjust the exponent.
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        digits[0] = '1';
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ++decimalAt;
39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        maximumDigits = 0; // Adjust the count
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break;
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    ++digits[maximumDigits];
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (digits[maximumDigits] <= '9') break;
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this
39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ++maximumDigits; // Increment for use as count
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            count = maximumDigits;
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Eliminate trailing zeros.
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (count > 1 && digits[count-1] == '0') {
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                --count;
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Return true if truncating the representation to the given number
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * of digits will result in an increment to the last digit.  This
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * method implements the rounding modes defined in the
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * java.math.RoundingMode class.
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * [bnf]
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param maximumDigits the number of digits to keep, from 0 to
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>count-1</code>.  If 0, then all digits are rounded away, and
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * this method returns true if a one should be generated (e.g., formatting
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * 0.09 with "#.#").
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception ArithmeticException if rounding is needed with rounding
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *            mode being set to RoundingMode.UNNECESSARY
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true if digit <code>maximumDigits-1</code> should be
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * incremented
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean shouldRoundUp(int maximumDigits) {
42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (maximumDigits < count) {
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            switch(roundingMode) {
42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case UP:
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (int i=maximumDigits; i<count; ++i) {
43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (digits[i] != '0') {
43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return true;
43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case DOWN:
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case CEILING:
43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (int i=maximumDigits; i<count; ++i) {
44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (digits[i] != '0') {
44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return !isNegative;
44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case FLOOR:
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (int i=maximumDigits; i<count; ++i) {
44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (digits[i] != '0') {
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return isNegative;
44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case HALF_UP:
45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (digits[maximumDigits] >= '5') {
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return true;
45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case HALF_DOWN:
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (digits[maximumDigits] > '5') {
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return true;
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if (digits[maximumDigits] == '5' ) {
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for (int i=maximumDigits+1; i<count; ++i) {
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (digits[i] != '0') {
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return true;
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case HALF_EVEN:
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // Implement IEEE half-even rounding
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (digits[maximumDigits] > '5') {
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return true;
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if (digits[maximumDigits] == '5' ) {
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    for (int i=maximumDigits+1; i<count; ++i) {
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (digits[i] != '0') {
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return true;
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0);
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case UNNECESSARY:
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                for (int i=maximumDigits; i<count; ++i) {
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (digits[i] != '0') {
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new ArithmeticException(
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            "Rounding needed with the rounding mode being set to RoundingMode.UNNECESSARY");
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
48851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            default:
49051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                assert false;
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
49251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
49351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return false;
49451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
49551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Utility routine to set the value of the digit list from a long
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final void set(boolean isNegative, long source) {
50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        set(isNegative, source, 0);
50151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
50251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
50351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
50451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the digit list to a representation of the given long value.
50551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param isNegative Boolean value indicating whether the number is negative.
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param source Value to be converted; must be >= 0 or ==
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Long.MIN_VALUE.
50851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param maximumDigits The most digits which should be converted.
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If maximumDigits is lower than the number of significant digits
51051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in source, the representation will be rounded.  Ignored if <= 0.
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public final void set(boolean isNegative, long source, int maximumDigits) {
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.isNegative = isNegative;
51451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // This method does not expect a negative number. However,
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // "source" can be a Long.MIN_VALUE (-9223372036854775808),
51751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // if the number being formatted is a Long.MIN_VALUE.  In that
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // case, it will be formatted as -Long.MIN_VALUE, a number
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // which is outside the legal range of a long, but which can
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // be represented by DigitList.
52151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (source <= 0) {
52251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (source == Long.MIN_VALUE) {
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decimalAt = count = MAX_COUNT;
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                System.arraycopy(LONG_MIN_REP, 0, digits, 0, count);
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                decimalAt = count = 0; // Values <= 0 format as zero
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Rewritten to improve performance.  I used to call
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Long.toString(), which was about 4x slower than this code.
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int left = MAX_COUNT;
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int right;
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (source > 0) {
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                digits[--left] = (char)('0' + (source % 10));
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                source /= 10;
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            decimalAt = MAX_COUNT - left;
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Don't copy trailing zeros.  We are guaranteed that there is at
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // least one non-zero digit, so we don't have to check lower bounds.
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            for (right = MAX_COUNT - 1; digits[right] == '0'; --right)
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ;
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            count = right - left + 1;
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(digits, left, digits, 0, count);
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (maximumDigits > 0) round(maximumDigits);
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the digit list to a representation of the given BigDecimal value.
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * This method supports both fixed-point and exponential notation.
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param isNegative Boolean value indicating whether the number is negative.
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param source Value to be converted; must not be a value <= 0.
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param maximumDigits The most fractional or total digits which should
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * be converted.
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param fixedPoint If true, then maximumDigits is the maximum
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * fractional digits to be converted.  If false, total digits.
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    final void set(boolean isNegative, BigDecimal source, int maximumDigits, boolean fixedPoint) {
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String s = source.toString();
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        extendDigits(s.length());
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        set(isNegative, s, maximumDigits, fixedPoint);
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Set the digit list to a representation of the given BigInteger value.
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param isNegative Boolean value indicating whether the number is negative.
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param source Value to be converted; must be >= 0.
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param maximumDigits The most digits which should be converted.
57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If maximumDigits is lower than the number of significant digits
57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * in source, the representation will be rounded.  Ignored if <= 0.
57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    final void set(boolean isNegative, BigInteger source, int maximumDigits) {
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.isNegative = isNegative;
57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String s = source.toString();
57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int len = s.length();
57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        extendDigits(len);
57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        s.getChars(0, len, digits, 0);
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        decimalAt = len;
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int right;
58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (right = len - 1; right >= 0 && digits[right] == '0'; --right)
58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ;
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        count = right + 1;
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (maximumDigits > 0) {
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            round(maximumDigits);
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * equality test between two digit lists.
59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean equals(Object obj) {
59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (this == obj)                      // quick check
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return true;
59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (!(obj instanceof DigitList))         // (1) same object?
59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        DigitList other = (DigitList) obj;
60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (count != other.count ||
60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        decimalAt != other.decimalAt)
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < count; i++)
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (digits[i] != other.digits[i])
60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return true;
60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Generates the hash code for the digit list.
61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int hashCode() {
61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int hashcode = decimalAt;
61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < count; i++) {
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            hashcode = hashcode * 37 + digits[i];
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return hashcode;
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Creates a copy of this object.
62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return a clone of this instance.
62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Object clone() {
62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            DigitList other = (DigitList) super.clone();
62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            char[] newDigits = new char[digits.length];
63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(digits, 0, newDigits, 0, digits.length);
63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            other.digits = newDigits;
63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            other.tempBuffer = null;
63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return other;
63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (CloneNotSupportedException e) {
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new InternalError();
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns true if this DigitList represents Long.MIN_VALUE;
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * false, otherwise.  This is required so that getLong() works.
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean isLongMIN_VALUE() {
64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (decimalAt != count || count != MAX_COUNT) {
64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        for (int i = 0; i < count; ++i) {
64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (digits[i] != LONG_MIN_REP[i]) return false;
65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return true;
65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int parseInt(char[] str, int offset, int strLen) {
65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        char c;
65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        boolean positive = true;
65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if ((c = str[offset]) == '-') {
65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            positive = false;
66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            offset++;
66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else if (c == '+') {
66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            offset++;
66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int value = 0;
66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        while (offset < strLen) {
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            c = str[offset++];
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (c >= '0' && c <= '9') {
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                value = value * 10 + (c - '0');
67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            } else {
67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return positive ? value : -value;
67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // The digit part of -9223372036854775808L
67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final char[] LONG_MIN_REP = "9223372036854775808".toCharArray();
67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString() {
68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (isZero()) {
68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return "0";
68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        StringBuffer buf = getStringBuffer();
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        buf.append("0.");
68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        buf.append(digits, 0, count);
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        buf.append("x10^");
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        buf.append(decimalAt);
68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return buf.toString();
69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private StringBuffer tempBuffer;
69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private StringBuffer getStringBuffer() {
69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (tempBuffer == null) {
69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            tempBuffer = new StringBuffer(MAX_COUNT);
69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } else {
69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            tempBuffer.setLength(0);
69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return tempBuffer;
70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void extendDigits(int len) {
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (len > digits.length) {
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            digits = new char[len];
70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private final char[] getDataChars(int length) {
71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (data == null || data.length < length) {
71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            data = new char[length];
71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return data;
71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
716