12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */ 2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License 42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* 52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Copyright (C) 1996-2015, International Business Machines Corporation and * 72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * others. All Rights Reserved. * 82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ******************************************************************************* 92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.text; 112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.math.BigInteger; 132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/** 152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>DigitList</code> handles the transcoding between numeric values and 162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * strings of characters. It only represents non-negative numbers. The 172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * division of labor between <code>DigitList</code> and 182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>DecimalFormat</code> is that <code>DigitList</code> handles the radix 192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 10 representation issues and numeric conversion, including rounding; 202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>DecimalFormat</code> handles the locale-specific issues such as 212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * positive and negative representation, digit grouping, decimal point, 222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * currency, and so on. 232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>A <code>DigitList</code> is a representation of a finite numeric value. 252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>DigitList</code> objects do not represent <code>NaN</code> or infinite 262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * values. A <code>DigitList</code> value can be converted to a 272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>BigDecimal</code> without loss of precision. Conversion to other 282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * numeric formats may involve loss of precision, depending on the specific 292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * value. 302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>The <code>DigitList</code> representation consists of a string of 322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * characters, which are the digits radix 10, from '0' to '9'. It also has a 332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * base 10 exponent associated with it. The value represented by a 342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>DigitList</code> object can be computed by mulitplying the fraction 352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <em>f</em>, where 0 <= <em>f</em> < 1, derived by placing all the digits of 362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the list to the right of the decimal point, by 10^exponent. 372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see java.util.Locale 392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see java.text.Format 402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see NumberFormat 412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see DecimalFormat 422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see java.text.ChoiceFormat 432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @see java.text.MessageFormat 442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @version 1.18 08/12/98 452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @author Mark Davis, Alan Liu 463b84259b78fc811b14079dfde655d68a389b36dbPaul Duffin * @hide Made public for testing 472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * */ 483b84259b78fc811b14079dfde655d68a389b36dbPaul Duffinpublic final class DigitList { 492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The maximum number of significant digits in an IEEE 754 double, that 512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is, in a Java double. This must not be increased, or garbage digits 522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * will be generated, and should not be decreased, or accuracy will be lost. 532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final int MAX_LONG_DIGITS = 19; // == Long.toString(Long.MAX_VALUE).length() 552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public static final int DBL_DIG = 17; 562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * These data members are intentionally public and can be set directly. 592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The value represented is given by placing the decimal point before 612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * digits[decimalAt]. If decimalAt is < 0, then leading zeros between 622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the decimal point and the first nonzero digit are implied. If decimalAt 632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is > count, then trailing zeros between the digits[count-1] and the 642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * decimal point are implied. 652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Equivalently, the represented value is given by f * 10^decimalAt. Here 672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * f is a value 0.1 <= f < 1 arrived at by placing the digits in Digits to 682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * the right of the decimal. 692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * DigitList is normalized, so if it is non-zero, figits[0] is non-zero. We 712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * don't allow denormalized numbers because our exponent is effectively of 722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * unlimited magnitude. The count value contains the number of significant 732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * digits present in digits[]. 742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Zero is represented by any DigitList with count == 0 or with each digits[i] 762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * for all i <= count == '0'. 772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int decimalAt = 0; 792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int count = 0; 802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public byte[] digits = new byte[MAX_LONG_DIGITS]; 812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private final void ensureCapacity(int digitCapacity, int digitsToCopy) { 832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (digitCapacity > digits.length) { 842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller byte[] newDigits = new byte[digitCapacity * 2]; 852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(digits, 0, newDigits, 0, digitsToCopy); 862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits = newDigits; 872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return true if the represented number is zero. 922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean isZero() 942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i=0; i<count; ++i) if (digits[i] != '0') return false; 962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// Unused as of ICU 2.6 - alan 1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// /** 1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * Clears out the digits. 1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * Use before appending them. 1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * Typically, you set a series of digits with append, then at the point 1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * you hit the decimal point, you set myDigitList.decimalAt = myDigitList.count; 1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * then go on appending digits. 1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// */ 1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// public void clear () { 1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// decimalAt = 0; 1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// count = 0; 1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// } 1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Appends digits to the list. 1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public void append (int digit) { 1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ensureCapacity(count+1, count); 1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits[count++] = (byte) digit; 1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public byte getDigitValue(int i) { 1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return (byte) (digits[i] - '0'); 1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Utility routine to get the value of the digit list 1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If (count == 0) this throws a NumberFormatException, which 1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * mimics Long.parseLong(). 1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final double getDouble() { 1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 0) return 0.0; 1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder temp = new StringBuilder(count); 1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller temp.append('.'); 1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < count; ++i) temp.append((char)(digits[i])); 1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller temp.append('E'); 1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller temp.append(Integer.toString(decimalAt)); 1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Double.valueOf(temp.toString()).doubleValue(); 1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // long value = Long.parseLong(temp.toString()); 1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // return (value * Math.pow(10, decimalAt - count)); 1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Utility routine to get the value of the digit list. 1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If (count == 0) this returns 0, unlike Long.parseLong(). 1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final long getLong() { 1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for now, simple implementation; later, do proper IEEE native stuff 1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count == 0) return 0; 1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We have to check for this, because this is the one NEGATIVE value 1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we represent. If we tried to just pass the digits off to parseLong, 1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we'd get a parse failure. 1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isLongMIN_VALUE()) return Long.MIN_VALUE; 1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder temp = new StringBuilder(count); 1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < decimalAt; ++i) 1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller temp.append((i < count) ? (char)(digits[i]) : '0'); 1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return Long.parseLong(temp.toString()); 1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return a <code>BigInteger</code> representing the value stored in this 1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>DigitList</code>. This method assumes that this object contains 1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * an integral value; if not, it will return an incorrect value. 1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * [bnf] 1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param isPositive determines the sign of the returned result 1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the value of this object as a <code>BigInteger</code> 1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public BigInteger getBigInteger(boolean isPositive) { 1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isZero()) return BigInteger.valueOf(0); 1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller //Eclipse stated the following is "dead code" 1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*if (false) { 1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder stringRep = new StringBuilder(count); 1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isPositive) { 1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append('-'); 1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i=0; i<count; ++i) { 1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append((char) digits[i]); 1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int d = decimalAt; 1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (d-- > count) { 1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append('0'); 1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new BigInteger(stringRep.toString()); 1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else*/ { 1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int len = decimalAt > count ? decimalAt : count; 1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isPositive) { 1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller len += 1; 1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char[] text = new char[len]; 1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int n = 0; 1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isPositive) { 1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text[0] = '-'; 1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < count; ++i) { 1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text[i+1] = (char)digits[i]; 1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller n = count+1; 2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < count; ++i) { 2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text[i] = (char)digits[i]; 2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller n = count; 2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = n; i < text.length; ++i) { 2072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller text[i] = '0'; 2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new BigInteger(new String(text)); 2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private String getStringRep(boolean isPositive) { 2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isZero()) return "0"; 2152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder stringRep = new StringBuilder(count+1); 2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isPositive) { 2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append('-'); 2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int d = decimalAt; 2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (d < 0) { 2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append('.'); 2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (d < 0) { 2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append('0'); 2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++d; 2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller d = -1; 2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i=0; i<count; ++i) { 2292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (d == i) { 2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append('.'); 2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append((char) digits[i]); 2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (d-- > count) { 2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller stringRep.append('0'); 2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return stringRep.toString(); 2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return an <code>ICU BigDecimal</code> representing the value stored in this 2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>DigitList</code>. 2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * [bnf] 2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param isPositive determines the sign of the returned result 2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return the value of this object as a <code>BigDecimal</code> 2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public android.icu.math.BigDecimal getBigDecimalICU(boolean isPositive) { 2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isZero()) { 2492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return android.icu.math.BigDecimal.valueOf(0); 2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if exponential notion is negative, 2522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we prefer to use BigDecimal constructor with scale, 2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // because it works better when extremely small value 2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // is used. See #5698. 2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long scale = (long)count - (long)decimalAt; 2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (scale > 0) { 2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int numDigits = count; 2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (scale > (long)Integer.MAX_VALUE) { 2592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // try to reduce the scale 2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller long numShift = scale - (long)Integer.MAX_VALUE; 2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (numShift < count) { 2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller numDigits -= numShift; 2632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // fallback to 0 2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new android.icu.math.BigDecimal(0); 2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder significantDigits = new StringBuilder(numDigits + 1); 2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!isPositive) { 2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller significantDigits.append('-'); 2712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < numDigits; i++) { 2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller significantDigits.append((char)digits[i]); 2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller BigInteger unscaledVal = new BigInteger(significantDigits.toString()); 2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new android.icu.math.BigDecimal(unscaledVal, (int)scale); 2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return new android.icu.math.BigDecimal(getStringRep(isPositive)); 2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return whether or not this objects represented value is an integer. 2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * [bnf] 2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return true if the represented value of this object is an integer 2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean isIntegral() { 2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Trim trailing zeros. This does not change the represented value. 2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (count > 0 && digits[count - 1] == (byte)'0') --count; 2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return count == 0 || decimalAt >= count; 2912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 2922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// Unused as of ICU 2.6 - alan 2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// /** 2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * Return true if the number represented by this object can fit into 2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * a long. 2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// */ 2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// boolean fitsIntoLong(boolean isPositive) 2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// { 3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // Figure out if the result will fit in a long. We have to 3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // first look for nonzero digits after the decimal point; 3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // then check the size. If the digit count is 18 or less, then 3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // the value can definitely be represented as a long. If it is 19 3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // then it may be too large. 3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// 3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // Trim trailing zeros. This does not change the represented value. 3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// while (count > 0 && digits[count - 1] == (byte)'0') --count; 3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// 3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// if (count == 0) { 3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // Positive zero fits into a long, but negative zero can only 3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // be represented as a double. - bug 4162852 3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// return isPositive; 3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// } 3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// 3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// if (decimalAt < count || decimalAt > MAX_LONG_DIGITS) return false; 3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// 3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// if (decimalAt < MAX_LONG_DIGITS) return true; 3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// 3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // At this point we have decimalAt == count, and count == MAX_LONG_DIGITS. 3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // The number will overflow if it is larger than 9223372036854775807 3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // or smaller than -9223372036854775808. 3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// for (int i=0; i<count; ++i) 3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// { 3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// byte dig = digits[i], max = LONG_MIN_REP[i]; 3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// if (dig > max) return false; 3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// if (dig < max) return true; 3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// } 3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// 3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // At this point the first count digits match. If decimalAt is less 3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // than count, then the remaining digits are zero, and we return true. 3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// if (count < decimalAt) return true; 3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// 3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // Now we have a representation of Long.MIN_VALUE, without the leading 3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // negative sign. If this represents a positive value, then it does 3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // not fit; otherwise it fits. 3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// return !isPositive; 3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// } 3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// Unused as of ICU 2.6 - alan 3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// /** 3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * Set the digit list to a representation of the given double value. 3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * This method supports fixed-point notation. 3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * @param source Value to be converted; must not be Inf, -Inf, Nan, 3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * or a value <= 0. 3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * @param maximumFractionDigits The most fractional digits which should 3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * be converted. 3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// */ 3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// public final void set(double source, int maximumFractionDigits) 3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// { 3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// set(source, maximumFractionDigits, true); 3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// } 3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Set the digit list to a representation of the given double value. 3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This method supports both fixed-point and exponential notation. 3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param source Value to be converted; must not be Inf, -Inf, Nan, 3572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * or a value <= 0. 3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param maximumDigits The most fractional or total digits which should 3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * be converted. 3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fixedPoint If true, then maximumDigits is the maximum 3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * fractional digits to be converted. If false, total digits. 3622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller final void set(double source, int maximumDigits, boolean fixedPoint) 3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (source == 0) source = 0; 3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Generate a representation of the form DDDDD, DDDDD.DDDDD, or 3672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // DDDDDE+/-DDDDD. 3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String rep = Double.toString(source); 3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller didRound = false; 3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller set(rep, MAX_LONG_DIGITS); 3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (fixedPoint) { 3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // The negative of the exponent represents the number of leading 3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // zeros between the decimal and the first non-zero digit, for 3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // a value < 0.1 (e.g., for 0.00123, -decimalAt == 2). If this 3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // is more than the maximum fraction digits, then we have an underflow 3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // for the printed representation. 3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (-decimalAt > maximumDigits) { 3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = 0; 3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (-decimalAt == maximumDigits) { 3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (shouldRoundUp(0)) { 3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = 1; 3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++decimalAt; 3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits[0] = (byte)'1'; 3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = 0; 3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return; 3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // else fall through 3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Eliminate trailing zeros. 3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (count > 1 && digits[count - 1] == '0') 3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller --count; 3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Eliminate digits beyond maximum digits to be displayed. 4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Round up if appropriate. 4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits); 4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Given a string representation of the form DDDDD, DDDDD.DDDDD, 4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * or DDDDDE+/-DDDDD, set this object's value to it. Ignore 4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * any leading '-'. 4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void set(String rep, int maxCount) { 4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalAt = -1; 4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = 0; 4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int exponent = 0; 4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Number of zeros between decimal point and first non-zero digit after 4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // decimal point, for numbers < 1. 4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int leadingZerosAfterDecimal = 0; 4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller boolean nonZeroDigitSeen = false; 4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Skip over leading '-' 4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int i=0; 4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rep.charAt(i) == '-') { 4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++i; 4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (; i < rep.length(); ++i) { 4242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller char c = rep.charAt(i); 4252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (c == '.') { 4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalAt = count; 4272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (c == 'e' || c == 'E') { 4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++i; 4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Integer.parseInt doesn't handle leading '+' signs 4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (rep.charAt(i) == '+') { 4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++i; 4322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller exponent = Integer.valueOf(rep.substring(i)).intValue(); 4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (count < maxCount) { 4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!nonZeroDigitSeen) { 4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller nonZeroDigitSeen = (c != '0'); 4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!nonZeroDigitSeen && decimalAt != -1) { 4392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++leadingZerosAfterDecimal; 4402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (nonZeroDigitSeen) { 4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ensureCapacity(count+1, count); 4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits[count++] = (byte)c; 4462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (decimalAt == -1) { 4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalAt = count; 4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalAt += exponent - leadingZerosAfterDecimal; 4532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Return true if truncating the representation to the given number 4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * of digits will result in an increment to the last digit. This 4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * method implements half-even rounding, the default rounding mode. 4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * [bnf] 4602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param maximumDigits the number of digits to keep, from 0 to 4612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <code>count-1</code>. If 0, then all digits are rounded away, and 4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * this method returns true if a one should be generated (e.g., formatting 4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * 0.09 with "#.#"). 4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @return true if digit <code>maximumDigits-1</code> should be 4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * incremented 4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean shouldRoundUp(int maximumDigits) { 4682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // variable not used boolean increment = false; 4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Implement IEEE half-even rounding 4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /*Bug 4243108 4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller format(0.0) gives "0.1" if preceded by parse("99.99") [Richard/GCL] 4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (maximumDigits < count) { 4742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (digits[maximumDigits] > '5') { 4752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else if (digits[maximumDigits] == '5' ) { 4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i=maximumDigits+1; i<count; ++i) { 4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (digits[i] != '0') { 4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0); 4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Round the representation to the given number of digits. 4902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param maximumDigits The maximum number of digits to be shown. 4912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Upon return, count will be less than or equal to maximumDigits. 4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This now performs rounding when maximumDigits is 0, formerly it did not. 4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void round(int maximumDigits) { 4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Eliminate digits beyond maximum digits to be displayed. 4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Round up if appropriate. 4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // [bnf] rewritten to fix 4179818 4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (maximumDigits >= 0 && maximumDigits < count) { 4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (shouldRoundUp(maximumDigits)) { 5002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Rounding up involves incrementing digits from LSD to MSD. 5012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // In most cases this is simple, but in a worst case situation 5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // (9999..99) we have to adjust the decimalAt value. 5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (;;) 5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller --maximumDigits; 5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (maximumDigits < 0) 5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 5082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // We have all 9's, so we increment to a single digit 5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // of one and adjust the exponent. 5102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits[0] = (byte) '1'; 5112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++decimalAt; 5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller maximumDigits = 0; // Adjust the count 5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller didRound = true; 5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller break; 5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++digits[maximumDigits]; 5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller didRound = true; 5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (digits[maximumDigits] <= '9') break; 5202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this 5212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++maximumDigits; // Increment for use as count 5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = maximumDigits; 5252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Bug 4217661 DecimalFormat formats 1.001 to "1.00" instead of "1" 5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Eliminate trailing zeros. [Richard/GCL] 5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // [dlf] moved outside if block, see ticket #6408 5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (count > 1 && digits[count-1] == '0') { 5302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller --count; 5312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Value to indicate that rounding was done. 5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean didRound = false; 5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Indicates if last digit set was rounded or not. 5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * true indicates it was rounded. 5402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * false indicates rounding has not been done. 5412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean wasRounded() { 5432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return didRound; 5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Utility routine to set the value of the digit list from a long 5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void set(long source) 5502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 5512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller set(source, 0); 5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Set the digit list to a representation of the given long value. 5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param source Value to be converted; must be >= 0 or == 5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Long.MIN_VALUE. 5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param maximumDigits The most digits which should be converted. 5592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If maximumDigits is lower than the number of significant digits 5602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in source, the representation will be rounded. Ignored if <= 0. 5612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void set(long source, int maximumDigits) 5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // This method does not expect a negative number. However, 5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // "source" can be a Long.MIN_VALUE (-9223372036854775808), 5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // if the number being formatted is a Long.MIN_VALUE. In that 5672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // case, it will be formatted as -Long.MIN_VALUE, a number 5682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // which is outside the legal range of a long, but which can 5692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // be represented by DigitList. 5702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // [NEW] Faster implementation 5712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller didRound = false; 5722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (source <= 0) { 5742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (source == Long.MIN_VALUE) { 5752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalAt = count = MAX_LONG_DIGITS; 5762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(LONG_MIN_REP, 0, digits, 0, count); 5772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 5782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = 0; 5792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalAt = 0; 5802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } else { 5822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int left = MAX_LONG_DIGITS; 5832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int right; 5842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (source > 0) { 5852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits[--left] = (byte) (((long) '0') + (source % 10)); 5862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller source /= 10; 5872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalAt = MAX_LONG_DIGITS-left; 5892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Don't copy trailing zeros 5902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // we are guaranteed that there is at least one non-zero digit, 5912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // so we don't have to check lower bounds 5922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (right = MAX_LONG_DIGITS - 1; digits[right] == (byte) '0'; --right) {} 5932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = right - left + 1; 5942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller System.arraycopy(digits, left, digits, 0, count); 5952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (maximumDigits > 0) round(maximumDigits); 5972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 5982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 5992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 6002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Set the digit list to a representation of the given BigInteger value. 6012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * [bnf] 6022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param source Value to be converted 6032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param maximumDigits The most digits which should be converted. 6042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If maximumDigits is lower than the number of significant digits 6052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in source, the representation will be rounded. Ignored if <= 0. 6062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 6072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void set(BigInteger source, int maximumDigits) { 6082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String stringDigits = source.toString(); 6092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller count = decimalAt = stringDigits.length(); 6112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller didRound = false; 6122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Don't copy trailing zeros 6142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller while (count > 1 && stringDigits.charAt(count - 1) == '0') --count; 6152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int offset = 0; 6172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (stringDigits.charAt(0) == '-') { 6182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ++offset; 6192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller --count; 6202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller --decimalAt; 6212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller ensureCapacity(count, 0); 6242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < count; ++i) { 6252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller digits[i] = (byte) stringDigits.charAt(i + offset); 6262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (maximumDigits > 0) round(maximumDigits); 6292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 6302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 6322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Internal method that sets this digit list to represent the 6332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * given value. The value is given as a String of the format 6342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * returned by BigDecimal. 6352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param stringDigits value to be represented with the following 6362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * syntax, expressed as a regular expression: -?\d*.?\d* 6372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Must not be an empty string. 6382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param maximumDigits The most digits which should be converted. 6392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If maximumDigits is lower than the number of significant digits 6402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in source, the representation will be rounded. Ignored if <= 0. 6412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fixedPoint If true, then maximumDigits is the maximum 6422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * fractional digits to be converted. If false, total digits. 6432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 6442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private void setBigDecimalDigits(String stringDigits, 6452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int maximumDigits, boolean fixedPoint) { 6462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| // Find the first non-zero digit, the decimal, and the last non-zero digit. 6472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| int first=-1, last=stringDigits.length()-1, decimal=-1; 6482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| for (int i=0; (first<0 || decimal<0) && i<=last; ++i) { 6492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| char c = stringDigits.charAt(i); 6502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| if (c == '.') { 6512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| decimal = i; 6522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } else if (first < 0 && (c >= '1' && c <= '9')) { 6532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| first = i; 6542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| 6572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| if (first < 0) { 6582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| clear(); 6592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| return; 6602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| 6622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| // At this point we know there is at least one non-zero digit, so the 6632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| // following loop is safe. 6642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| for (;;) { 6652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| char c = stringDigits.charAt(last); 6662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| if (c != '0' && c != '.') { 6672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| break; 6682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| --last; 6702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| 6722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| if (decimal < 0) { 6732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| decimal = stringDigits.length(); 6742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| 6762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| count = last - first; 6772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| if (decimal < first || decimal > last) { 6782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| ++count; 6792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| decimalAt = decimal - first; 6812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| if (decimalAt < 0) { 6822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| ++decimalAt; 6832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| 6852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| ensureCapacity(count, 0); 6862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| for (int i = 0; i < count; ++i) { 6872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| digits[i] = (byte) stringDigits.charAt(first++); 6882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| if (first == decimal) { 6892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| ++first; 6902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller//| } 6922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller didRound = false; 6942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // The maxDigits here could also be Integer.MAX_VALUE 6962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller set(stringDigits, stringDigits.length()); 6972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 6982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Eliminate digits beyond maximum digits to be displayed. 6992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Round up if appropriate. 7002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // {dlf} Some callers depend on passing '0' to round to mean 'don't round', but 7012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // rather than pass that information explicitly, we rely on some magic with maximumDigits 7022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // and decimalAt. Unfortunately, this is no good, because there are cases where maximumDigits 7032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // is zero and we do want to round, e.g. BigDecimal values -1 < x < 1. So since round 7042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // changed to perform rounding when the argument is 0, we now force the argument 7052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // to -1 in the situations where it matters. 7062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits); 7072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 7102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Set the digit list to a representation of the given BigDecimal value. 7112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * [bnf] 7122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param source Value to be converted 7132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param maximumDigits The most digits which should be converted. 7142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If maximumDigits is lower than the number of significant digits 7152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in source, the representation will be rounded. Ignored if <= 0. 7162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fixedPoint If true, then maximumDigits is the maximum 7172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * fractional digits to be converted. If false, total digits. 7182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void set(java.math.BigDecimal source, 7202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int maximumDigits, boolean fixedPoint) { 7212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint); 7222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /* 7252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Set the digit list to a representation of the given BigDecimal value. 7262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * [bnf] 7272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param source Value to be converted 7282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param maximumDigits The most digits which should be converted. 7292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * If maximumDigits is lower than the number of significant digits 7302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * in source, the representation will be rounded. Ignored if <= 0. 7312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * @param fixedPoint If true, then maximumDigits is the maximum 7322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * fractional digits to be converted. If false, total digits. 7332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public final void set(android.icu.math.BigDecimal source, 7352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int maximumDigits, boolean fixedPoint) { 7362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint); 7372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 7402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Returns true if this DigitList represents Long.MIN_VALUE; 7412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * false, otherwise. This is required so that getLong() works. 7422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 7432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private boolean isLongMIN_VALUE() 7442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 7452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (decimalAt != count || count != MAX_LONG_DIGITS) 7462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 7472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < count; ++i) 7492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 7502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (digits[i] != LONG_MIN_REP[i]) return false; 7512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 7542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller private static byte[] LONG_MIN_REP; 7572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller static 7592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 7602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller // Store the representation of LONG_MIN without the leading '-' 7612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller String s = Long.toString(Long.MIN_VALUE); 7622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller LONG_MIN_REP = new byte[MAX_LONG_DIGITS]; 7632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i=0; i < MAX_LONG_DIGITS; ++i) 7642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 7652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller LONG_MIN_REP[i] = (byte)s.charAt(i + 1); 7662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 7682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// Unused -- Alan 2003-05 7702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// /** 7712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * Return the floor of the log base 10 of a given double. 7722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * This method compensates for inaccuracies which arise naturally when 7732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * computing logs, and always give the correct value. The parameter 7742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// * must be positive and finite. 7752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// */ 7762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// private static final int log10(double d) 7772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// { 7782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // The reason this routine is needed is that simply taking the 7792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // log and dividing by log10 yields a result which may be off 7802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // by 1 due to rounding errors. For example, the naive log10 7812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // of 1.0e300 taken this way is 299, rather than 300. 7822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// double log10 = Math.log(d) / LOG10; 7832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// int ilog10 = (int)Math.floor(log10); 7842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // Positive logs could be too small, e.g. 0.99 instead of 1.0 7852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// if (log10 > 0 && d >= Math.pow(10, ilog10 + 1)) 7862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// { 7872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// ++ilog10; 7882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// } 7892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// // Negative logs could be too big, e.g. -0.99 instead of -1.0 7902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// else if (log10 < 0 && d < Math.pow(10, ilog10)) 7912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// { 7922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// --ilog10; 7932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// } 7942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// return ilog10; 7952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// } 7962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// 7972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller// private static final double LOG10 = Math.log(10.0); 7982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 7992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * equality test between two digit lists. 8012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public boolean equals(Object obj) { 8032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (this == obj) // quick check 8042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 8052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (!(obj instanceof DigitList)) // (1) same object? 8062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 8072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller DigitList other = (DigitList) obj; 8082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (count != other.count || 8092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller decimalAt != other.decimalAt) 8102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 8112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < count; i++) 8122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (digits[i] != other.digits[i]) 8132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return false; 8142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return true; 8152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller /** 8182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Generates the hash code for the digit list. 8192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */ 8202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public int hashCode() { 8212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller int hashcode = decimalAt; 8222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i = 0; i < count; i++) 8242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller hashcode = hashcode * 37 + digits[i]; 8252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return hashcode; 8272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller 8292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller public String toString() 8302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller { 8312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller if (isZero()) return "0"; 8322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller StringBuilder buf = new StringBuilder("0."); 8332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller for (int i=0; i<count; ++i) buf.append((char)digits[i]); 8342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append("x10^"); 8352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller buf.append(decimalAt); 8362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller return buf.toString(); 8372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller } 8382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller} 839