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