17935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/* 27935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Copyright (C) 1996-2011, International Business Machines Corporation and * 47935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved. * 57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ******************************************************************************* 67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.text; 87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.math.BigInteger; 107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/** 127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>DigitList</code> handles the transcoding between numeric values and 137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * strings of characters. It only represents non-negative numbers. The 147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * division of labor between <code>DigitList</code> and 157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>DecimalFormat</code> is that <code>DigitList</code> handles the radix 167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 10 representation issues and numeric conversion, including rounding; 177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>DecimalFormat</code> handles the locale-specific issues such as 187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * positive and negative representation, digit grouping, decimal point, 197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * currency, and so on. 207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>A <code>DigitList</code> is a representation of a finite numeric value. 227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>DigitList</code> objects do not represent <code>NaN</code> or infinite 237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * values. A <code>DigitList</code> value can be converted to a 247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>BigDecimal</code> without loss of precision. Conversion to other 257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * numeric formats may involve loss of precision, depending on the specific 267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * value. 277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <p>The <code>DigitList</code> representation consists of a string of 297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * characters, which are the digits radix 10, from '0' to '9'. It also has a 307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * base 10 exponent associated with it. The value represented by a 317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>DigitList</code> object can be computed by mulitplying the fraction 327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <em>f</em>, where 0 <= <em>f</em> < 1, derived by placing all the digits of 337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the list to the right of the decimal point, by 10^exponent. 347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see java.util.Locale 367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see java.text.Format 377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see NumberFormat 387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see DecimalFormat 397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see java.text.ChoiceFormat 407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @see java.text.MessageFormat 417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @version 1.18 08/12/98 427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @author Mark Davis, Alan Liu 437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * */ 447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertfinal class DigitList { 457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The maximum number of significant digits in an IEEE 754 double, that 477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is, in a Java double. This must not be increased, or garbage digits 487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * will be generated, and should not be decreased, or accuracy will be lost. 497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int MAX_LONG_DIGITS = 19; // == Long.toString(Long.MAX_VALUE).length() 517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public static final int DBL_DIG = 17; 527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * These data members are intentionally public and can be set directly. 557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * The value represented is given by placing the decimal point before 577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * digits[decimalAt]. If decimalAt is < 0, then leading zeros between 587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the decimal point and the first nonzero digit are implied. If decimalAt 597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * is > count, then trailing zeros between the digits[count-1] and the 607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * decimal point are implied. 617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Equivalently, the represented value is given by f * 10^decimalAt. Here 637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * f is a value 0.1 <= f < 1 arrived at by placing the digits in Digits to 647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * the right of the decimal. 657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * DigitList is normalized, so if it is non-zero, figits[0] is non-zero. We 677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * don't allow denormalized numbers because our exponent is effectively of 687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * unlimited magnitude. The count value contains the number of significant 697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * digits present in digits[]. 707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Zero is represented by any DigitList with count == 0 or with each digits[i] 727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * for all i <= count == '0'. 737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int decimalAt = 0; 757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int count = 0; 767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public byte[] digits = new byte[MAX_LONG_DIGITS]; 777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private final void ensureCapacity(int digitCapacity, int digitsToCopy) { 797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (digitCapacity > digits.length) { 807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert byte[] newDigits = new byte[digitCapacity * 2]; 817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert System.arraycopy(digits, 0, newDigits, 0, digitsToCopy); 827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert digits = newDigits; 837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return true if the represented number is zero. 887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isZero() 907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i=0; i<count; ++i) if (digits[i] != '0') return false; 927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// Unused as of ICU 2.6 - alan 967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// /** 977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * Clears out the digits. 987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * Use before appending them. 997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * Typically, you set a series of digits with append, then at the point 1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * you hit the decimal point, you set myDigitList.decimalAt = myDigitList.count; 1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * then go on appending digits. 1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// */ 1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// public void clear () { 1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// decimalAt = 0; 1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// count = 0; 1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Appends digits to the list. 1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public void append (int digit) { 1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ensureCapacity(count+1, count); 1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert digits[count++] = (byte) digit; 1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public byte getDigitValue(int i) { 1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return (byte) (digits[i] - '0'); 1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Utility routine to get the value of the digit list 1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If (count == 0) this throws a NumberFormatException, which 1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * mimics Long.parseLong(). 1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final double getDouble() { 1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (count == 0) return 0.0; 1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder temp = new StringBuilder(count); 1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert temp.append('.'); 1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; ++i) temp.append((char)(digits[i])); 1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert temp.append('E'); 1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert temp.append(Integer.toString(decimalAt)); 1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Double.valueOf(temp.toString()).doubleValue(); 1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // long value = Long.parseLong(temp.toString()); 1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // return (value * Math.pow(10, decimalAt - count)); 1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Utility routine to get the value of the digit list. 1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If (count == 0) this returns 0, unlike Long.parseLong(). 1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final long getLong() { 1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // for now, simple implementation; later, do proper IEEE native stuff 1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (count == 0) return 0; 1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // We have to check for this, because this is the one NEGATIVE value 1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // we represent. If we tried to just pass the digits off to parseLong, 1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // we'd get a parse failure. 1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isLongMIN_VALUE()) return Long.MIN_VALUE; 1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder temp = new StringBuilder(count); 1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < decimalAt; ++i) 1537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert temp.append((i < count) ? (char)(digits[i]) : '0'); 1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return Long.parseLong(temp.toString()); 1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return a <code>BigInteger</code> representing the value stored in this 1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>DigitList</code>. This method assumes that this object contains 1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * an integral value; if not, it will return an incorrect value. 1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * [bnf] 1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param isPositive determines the sign of the returned result 1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the value of this object as a <code>BigInteger</code> 1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public BigInteger getBigInteger(boolean isPositive) { 1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isZero()) return BigInteger.valueOf(0); 1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert //Eclipse stated the following is "dead code" 1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /*if (false) { 1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder stringRep = new StringBuilder(count); 1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isPositive) { 1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append('-'); 1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i=0; i<count; ++i) { 1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append((char) digits[i]); 1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int d = decimalAt; 1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (d-- > count) { 1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append('0'); 1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new BigInteger(stringRep.toString()); 1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else*/ { 1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int len = decimalAt > count ? decimalAt : count; 1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isPositive) { 1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert len += 1; 1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert char[] text = new char[len]; 1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int n = 0; 1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isPositive) { 1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert text[0] = '-'; 1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; ++i) { 1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert text[i+1] = (char)digits[i]; 1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 1957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert n = count+1; 1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; ++i) { 1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert text[i] = (char)digits[i]; 1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert n = count; 2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = n; i < text.length; ++i) { 2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert text[i] = '0'; 2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new BigInteger(new String(text)); 2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private String getStringRep(boolean isPositive) { 2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isZero()) return "0"; 2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder stringRep = new StringBuilder(count+1); 2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isPositive) { 2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append('-'); 2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int d = decimalAt; 2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (d < 0) { 2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append('.'); 2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (d < 0) { 2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append('0'); 2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++d; 2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert d = -1; 2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i=0; i<count; ++i) { 2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (d == i) { 2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append('.'); 2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append((char) digits[i]); 2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (d-- > count) { 2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert stringRep.append('0'); 2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return stringRep.toString(); 2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return a <code>BigDecimal</code> representing the value stored in this 2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>DigitList</code>. 2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * [bnf] 2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param isPositive determines the sign of the returned result 2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the value of this object as a <code>BigDecimal</code> 2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:OFF 2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The method is in a protected class and is not called by anything 2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public java.math.BigDecimal getBigDecimal(boolean isPositive) { 2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isZero()) { 2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return java.math.BigDecimal.valueOf(0); 2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // if exponential notion is negative, 2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // we prefer to use BigDecimal constructor with scale, 2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // because it works better when extremely small value 2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // is used. See #5698. 2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long scale = (long)count - (long)decimalAt; 2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (scale > 0) { 2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int numDigits = count; 2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (scale > (long)Integer.MAX_VALUE) { 2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // try to reduce the scale 2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long numShift = scale - (long)Integer.MAX_VALUE; 2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (numShift < count) { 2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert numDigits -= numShift; 2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // fallback to 0 2637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new java.math.BigDecimal(0); 2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder significantDigits = new StringBuilder(numDigits + 1); 2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isPositive) { 2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert significantDigits.append('-'); 2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < numDigits; i++) { 2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert significantDigits.append((char)digits[i]); 2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigInteger unscaledVal = new BigInteger(significantDigits.toString()); 2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new java.math.BigDecimal(unscaledVal, (int)scale); 2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // We should be able to use a negative scale value for a positive exponential 2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // value on JDK1.5. But it is not supported by older JDK. So, for now, 2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // we always use BigDecimal constructor which takes String. 2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new java.math.BigDecimal(getStringRep(isPositive)); 2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:ON 2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return an <code>ICU BigDecimal</code> representing the value stored in this 2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>DigitList</code>. 2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * [bnf] 2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param isPositive determines the sign of the returned result 2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return the value of this object as a <code>BigDecimal</code> 2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public com.ibm.icu.math.BigDecimal getBigDecimalICU(boolean isPositive) { 2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isZero()) { 2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return com.ibm.icu.math.BigDecimal.valueOf(0); 2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // if exponential notion is negative, 2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // we prefer to use BigDecimal constructor with scale, 2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // because it works better when extremely small value 2987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // is used. See #5698. 2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long scale = (long)count - (long)decimalAt; 3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (scale > 0) { 3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int numDigits = count; 3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (scale > (long)Integer.MAX_VALUE) { 3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // try to reduce the scale 3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert long numShift = scale - (long)Integer.MAX_VALUE; 3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (numShift < count) { 3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert numDigits -= numShift; 3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // fallback to 0 3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new com.ibm.icu.math.BigDecimal(0); 3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder significantDigits = new StringBuilder(numDigits + 1); 3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!isPositive) { 3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert significantDigits.append('-'); 3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < numDigits; i++) { 3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert significantDigits.append((char)digits[i]); 3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert BigInteger unscaledVal = new BigInteger(significantDigits.toString()); 3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new com.ibm.icu.math.BigDecimal(unscaledVal, (int)scale); 3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return new com.ibm.icu.math.BigDecimal(getStringRep(isPositive)); 3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return whether or not this objects represented value is an integer. 3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * [bnf] 3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return true if the represented value of this object is an integer 3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean isIntegral() { 3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Trim trailing zeros. This does not change the represented value. 3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (count > 0 && digits[count - 1] == (byte)'0') --count; 3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return count == 0 || decimalAt >= count; 3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// Unused as of ICU 2.6 - alan 3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// /** 3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * Return true if the number represented by this object can fit into 3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * a long. 3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// */ 3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// boolean fitsIntoLong(boolean isPositive) 3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// { 3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // Figure out if the result will fit in a long. We have to 3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // first look for nonzero digits after the decimal point; 3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // then check the size. If the digit count is 18 or less, then 3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // the value can definitely be represented as a long. If it is 19 3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // then it may be too large. 3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// 3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // Trim trailing zeros. This does not change the represented value. 3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// while (count > 0 && digits[count - 1] == (byte)'0') --count; 3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// 3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (count == 0) { 3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // Positive zero fits into a long, but negative zero can only 3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // be represented as a double. - bug 4162852 3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// return isPositive; 3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// 3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (decimalAt < count || decimalAt > MAX_LONG_DIGITS) return false; 3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// 3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (decimalAt < MAX_LONG_DIGITS) return true; 3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// 3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // At this point we have decimalAt == count, and count == MAX_LONG_DIGITS. 3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // The number will overflow if it is larger than 9223372036854775807 3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // or smaller than -9223372036854775808. 3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// for (int i=0; i<count; ++i) 3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// { 3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// byte dig = digits[i], max = LONG_MIN_REP[i]; 3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (dig > max) return false; 3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (dig < max) return true; 3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// 3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // At this point the first count digits match. If decimalAt is less 3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // than count, then the remaining digits are zero, and we return true. 3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (count < decimalAt) return true; 3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// 3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // Now we have a representation of Long.MIN_VALUE, without the leading 3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // negative sign. If this represents a positive value, then it does 3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // not fit; otherwise it fits. 3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// return !isPositive; 3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// Unused as of ICU 2.6 - alan 3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// /** 3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * Set the digit list to a representation of the given double value. 3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * This method supports fixed-point notation. 3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * @param source Value to be converted; must not be Inf, -Inf, Nan, 3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * or a value <= 0. 3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * @param maximumFractionDigits The most fractional digits which should 3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * be converted. 3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// */ 3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// public final void set(double source, int maximumFractionDigits) 3937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// { 3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// set(source, maximumFractionDigits, true); 3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Set the digit list to a representation of the given double value. 3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This method supports both fixed-point and exponential notation. 4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param source Value to be converted; must not be Inf, -Inf, Nan, 4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * or a value <= 0. 4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param maximumDigits The most fractional or total digits which should 4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * be converted. 4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param fixedPoint If true, then maximumDigits is the maximum 4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * fractional digits to be converted. If false, total digits. 4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert final void set(double source, int maximumDigits, boolean fixedPoint) 4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (source == 0) source = 0; 4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Generate a representation of the form DDDDD, DDDDD.DDDDD, or 4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // DDDDDE+/-DDDDD. 4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String rep = Double.toString(source); 4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set(rep, MAX_LONG_DIGITS); 4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (fixedPoint) { 4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The negative of the exponent represents the number of leading 4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // zeros between the decimal and the first non-zero digit, for 4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // a value < 0.1 (e.g., for 0.00123, -decimalAt == 2). If this 4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // is more than the maximum fraction digits, then we have an underflow 4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // for the printed representation. 4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (-decimalAt > maximumDigits) { 4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = 0; 4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return; 4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (-decimalAt == maximumDigits) { 4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (shouldRoundUp(0)) { 4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = 1; 4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++decimalAt; 4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert digits[0] = (byte)'1'; 4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = 0; 4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return; 4347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // else fall through 4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Eliminate trailing zeros. 4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (count > 1 && digits[count - 1] == '0') 4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert --count; 4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Eliminate digits beyond maximum digits to be displayed. 4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Round up if appropriate. 4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits); 4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Given a string representation of the form DDDDD, DDDDD.DDDDD, 4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * or DDDDDE+/-DDDDD, set this object's value to it. Ignore 4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * any leading '-'. 4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void set(String rep, int maxCount) { 4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert decimalAt = -1; 4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = 0; 4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int exponent = 0; 4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Number of zeros between decimal point and first non-zero digit after 4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // decimal point, for numbers < 1. 4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int leadingZerosAfterDecimal = 0; 4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert boolean nonZeroDigitSeen = false; 4607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Skip over leading '-' 4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int i=0; 4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (rep.charAt(i) == '-') { 4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++i; 4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (; i < rep.length(); ++i) { 4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert char c = rep.charAt(i); 4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (c == '.') { 4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert decimalAt = count; 4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (c == 'e' || c == 'E') { 4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++i; 4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Integer.parseInt doesn't handle leading '+' signs 4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (rep.charAt(i) == '+') { 4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++i; 4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert exponent = Integer.valueOf(rep.substring(i)).intValue(); 4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (count < maxCount) { 4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!nonZeroDigitSeen) { 4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert nonZeroDigitSeen = (c != '0'); 4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!nonZeroDigitSeen && decimalAt != -1) { 4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++leadingZerosAfterDecimal; 4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (nonZeroDigitSeen) { 4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ensureCapacity(count+1, count); 4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert digits[count++] = (byte)c; 4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (decimalAt == -1) { 4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert decimalAt = count; 4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert decimalAt += exponent - leadingZerosAfterDecimal; 4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Return true if truncating the representation to the given number 4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * of digits will result in an increment to the last digit. This 5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * method implements half-even rounding, the default rounding mode. 5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * [bnf] 5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param maximumDigits the number of digits to keep, from 0 to 5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * <code>count-1</code>. If 0, then all digits are rounded away, and 5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * this method returns true if a one should be generated (e.g., formatting 5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * 0.09 with "#.#"). 5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @return true if digit <code>maximumDigits-1</code> should be 5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * incremented 5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private boolean shouldRoundUp(int maximumDigits) { 5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // variable not used boolean increment = false; 5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Implement IEEE half-even rounding 5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /*Bug 4243108 5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert format(0.0) gives "0.1" if preceded by parse("99.99") [Richard/GCL] 5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (maximumDigits < count) { 5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (digits[maximumDigits] > '5') { 5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else if (digits[maximumDigits] == '5' ) { 5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i=maximumDigits+1; i<count; ++i) { 5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (digits[i] != '0') { 5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0); 5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Round the representation to the given number of digits. 5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param maximumDigits The maximum number of digits to be shown. 5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Upon return, count will be less than or equal to maximumDigits. 5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * This now performs rounding when maximumDigits is 0, formerly it did not. 5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final void round(int maximumDigits) { 5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Eliminate digits beyond maximum digits to be displayed. 5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Round up if appropriate. 5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // [bnf] rewritten to fix 4179818 5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (maximumDigits >= 0 && maximumDigits < count) { 5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (shouldRoundUp(maximumDigits)) { 5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Rounding up involves incrementing digits from LSD to MSD. 5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // In most cases this is simple, but in a worst case situation 5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // (9999..99) we have to adjust the decimalAt value. 5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (;;) 5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert --maximumDigits; 5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (maximumDigits < 0) 5497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // We have all 9's, so we increment to a single digit 5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // of one and adjust the exponent. 5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert digits[0] = (byte) '1'; 5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++decimalAt; 5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert maximumDigits = 0; // Adjust the count 5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert break; 5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++digits[maximumDigits]; 5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (digits[maximumDigits] <= '9') break; 5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this 5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++maximumDigits; // Increment for use as count 5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = maximumDigits; 5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Bug 4217661 DecimalFormat formats 1.001 to "1.00" instead of "1" 5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Eliminate trailing zeros. [Richard/GCL] 5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // [dlf] moved outside if block, see ticket #6408 5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (count > 1 && digits[count-1] == '0') { 5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert --count; 5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Utility routine to set the value of the digit list from a long 5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final void set(long source) 5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set(source, 0); 5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Set the digit list to a representation of the given long value. 5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param source Value to be converted; must be >= 0 or == 5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Long.MIN_VALUE. 5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param maximumDigits The most digits which should be converted. 5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If maximumDigits is lower than the number of significant digits 5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in source, the representation will be rounded. Ignored if <= 0. 5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final void set(long source, int maximumDigits) 5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // This method does not expect a negative number. However, 5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // "source" can be a Long.MIN_VALUE (-9223372036854775808), 5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // if the number being formatted is a Long.MIN_VALUE. In that 5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // case, it will be formatted as -Long.MIN_VALUE, a number 5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // which is outside the legal range of a long, but which can 5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // be represented by DigitList. 5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // [NEW] Faster implementation 5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (source <= 0) { 6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (source == Long.MIN_VALUE) { 6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert decimalAt = count = MAX_LONG_DIGITS; 6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert System.arraycopy(LONG_MIN_REP, 0, digits, 0, count); 6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = 0; 6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert decimalAt = 0; 6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } else { 6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int left = MAX_LONG_DIGITS; 6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int right; 6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (source > 0) { 6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert digits[--left] = (byte) (((long) '0') + (source % 10)); 6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert source /= 10; 6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert decimalAt = MAX_LONG_DIGITS-left; 6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Don't copy trailing zeros 6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // we are guaranteed that there is at least one non-zero digit, 6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // so we don't have to check lower bounds 6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (right = MAX_LONG_DIGITS - 1; digits[right] == (byte) '0'; --right) {} 6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = right - left + 1; 6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert System.arraycopy(digits, left, digits, 0, count); 6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (maximumDigits > 0) round(maximumDigits); 6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Set the digit list to a representation of the given BigInteger value. 6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * [bnf] 6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param source Value to be converted 6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param maximumDigits The most digits which should be converted. 6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If maximumDigits is lower than the number of significant digits 6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in source, the representation will be rounded. Ignored if <= 0. 6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final void set(BigInteger source, int maximumDigits) { 6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String stringDigits = source.toString(); 6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert count = decimalAt = stringDigits.length(); 6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Don't copy trailing zeros 6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert while (count > 1 && stringDigits.charAt(count - 1) == '0') --count; 6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int offset = 0; 6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (stringDigits.charAt(0) == '-') { 6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ++offset; 6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert --count; 6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert --decimalAt; 6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ensureCapacity(count, 0); 6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; ++i) { 6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert digits[i] = (byte) stringDigits.charAt(i + offset); 6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (maximumDigits > 0) round(maximumDigits); 6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Internal method that sets this digit list to represent the 6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * given value. The value is given as a String of the format 6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * returned by BigDecimal. 6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param stringDigits value to be represented with the following 6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * syntax, expressed as a regular expression: -?\d*.?\d* 6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Must not be an empty string. 6637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param maximumDigits The most digits which should be converted. 6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If maximumDigits is lower than the number of significant digits 6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in source, the representation will be rounded. Ignored if <= 0. 6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param fixedPoint If true, then maximumDigits is the maximum 6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * fractional digits to be converted. If false, total digits. 6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private void setBigDecimalDigits(String stringDigits, 6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int maximumDigits, boolean fixedPoint) { 6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| // Find the first non-zero digit, the decimal, and the last non-zero digit. 6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| int first=-1, last=stringDigits.length()-1, decimal=-1; 6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| for (int i=0; (first<0 || decimal<0) && i<=last; ++i) { 6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| char c = stringDigits.charAt(i); 6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| if (c == '.') { 6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| decimal = i; 6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } else if (first < 0 && (c >= '1' && c <= '9')) { 6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| first = i; 6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| 6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| if (first < 0) { 6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| clear(); 6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| return; 6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 6867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| 6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| // At this point we know there is at least one non-zero digit, so the 6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| // following loop is safe. 6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| for (;;) { 6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| char c = stringDigits.charAt(last); 6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| if (c != '0' && c != '.') { 6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| break; 6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| --last; 6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| 6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| if (decimal < 0) { 6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| decimal = stringDigits.length(); 6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| 7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| count = last - first; 7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| if (decimal < first || decimal > last) { 7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| ++count; 7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| decimalAt = decimal - first; 7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| if (decimalAt < 0) { 7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| ++decimalAt; 7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| 7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| ensureCapacity(count, 0); 7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| for (int i = 0; i < count; ++i) { 7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| digits[i] = (byte) stringDigits.charAt(first++); 7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| if (first == decimal) { 7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| ++first; 7157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//| } 7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // The maxDigits here could also be Integer.MAX_VALUE 7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert set(stringDigits, stringDigits.length()); 7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Eliminate digits beyond maximum digits to be displayed. 7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Round up if appropriate. 7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // {dlf} Some callers depend on passing '0' to round to mean 'don't round', but 7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // rather than pass that information explicitly, we rely on some magic with maximumDigits 7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // and decimalAt. Unfortunately, this is no good, because there are cases where maximumDigits 7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // is zero and we do want to round, e.g. BigDecimal values -1 < x < 1. So since round 7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // changed to perform rounding when the argument is 0, we now force the argument 7287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // to -1 in the situations where it matters. 7297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits); 7307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Set the digit list to a representation of the given BigDecimal value. 7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * [bnf] 7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param source Value to be converted 7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param maximumDigits The most digits which should be converted. 7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If maximumDigits is lower than the number of significant digits 7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in source, the representation will be rounded. Ignored if <= 0. 7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param fixedPoint If true, then maximumDigits is the maximum 7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * fractional digits to be converted. If false, total digits. 7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final void set(java.math.BigDecimal source, 7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int maximumDigits, boolean fixedPoint) { 7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint); 7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /* 7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Set the digit list to a representation of the given BigDecimal value. 7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * [bnf] 7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param source Value to be converted 7517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param maximumDigits The most digits which should be converted. 7527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * If maximumDigits is lower than the number of significant digits 7537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * in source, the representation will be rounded. Ignored if <= 0. 7547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * @param fixedPoint If true, then maximumDigits is the maximum 7557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * fractional digits to be converted. If false, total digits. 7567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 7577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public final void set(com.ibm.icu.math.BigDecimal source, 7587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int maximumDigits, boolean fixedPoint) { 7597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint); 7607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 7637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Returns true if this DigitList represents Long.MIN_VALUE; 7647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * false, otherwise. This is required so that getLong() works. 7657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 7667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private boolean isLongMIN_VALUE() 7677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (decimalAt != count || count != MAX_LONG_DIGITS) 7697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 7707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; ++i) 7727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (digits[i] != LONG_MIN_REP[i]) return false; 7747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 7777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert private static byte[] LONG_MIN_REP; 7807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert static 7827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // Store the representation of LONG_MIN without the leading '-' 7847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert String s = Long.toString(Long.MIN_VALUE); 7857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LONG_MIN_REP = new byte[MAX_LONG_DIGITS]; 7867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i=0; i < MAX_LONG_DIGITS; ++i) 7877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 7887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert LONG_MIN_REP[i] = (byte)s.charAt(i + 1); 7897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 7917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 7927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// Unused -- Alan 2003-05 7937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// /** 7947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * Return the floor of the log base 10 of a given double. 7957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * This method compensates for inaccuracies which arise naturally when 7967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * computing logs, and always give the correct value. The parameter 7977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// * must be positive and finite. 7987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// */ 7997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// private static final int log10(double d) 8007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// { 8017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // The reason this routine is needed is that simply taking the 8027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // log and dividing by log10 yields a result which may be off 8037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // by 1 due to rounding errors. For example, the naive log10 8047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // of 1.0e300 taken this way is 299, rather than 300. 8057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// double log10 = Math.log(d) / LOG10; 8067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// int ilog10 = (int)Math.floor(log10); 8077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // Positive logs could be too small, e.g. 0.99 instead of 1.0 8087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// if (log10 > 0 && d >= Math.pow(10, ilog10 + 1)) 8097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// { 8107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// ++ilog10; 8117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 8127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// // Negative logs could be too big, e.g. -0.99 instead of -1.0 8137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// else if (log10 < 0 && d < Math.pow(10, ilog10)) 8147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// { 8157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// --ilog10; 8167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 8177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// return ilog10; 8187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// } 8197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// 8207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert// private static final double LOG10 = Math.log(10.0); 8217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // (The following boilerplate methods are currently not called, 8237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // and cannot be called by tests since this class is 8247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // package-private. The methods may be useful in the future, so 8257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert // we do not delete them. 2003-06-11 ICU 2.6 Alan) 8267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:OFF 8277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 8287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * equality test between two digit lists. 8297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public boolean equals(Object obj) { 8317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (this == obj) // quick check 8327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 8337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (!(obj instanceof DigitList)) // (1) same object? 8347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 8357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert DigitList other = (DigitList) obj; 8367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (count != other.count || 8377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert decimalAt != other.decimalAt) 8387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 8397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; i++) 8407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (digits[i] != other.digits[i]) 8417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return false; 8427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return true; 8437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert /** 8467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Generates the hash code for the digit list. 8477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */ 8487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public int hashCode() { 8497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert int hashcode = decimalAt; 8507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i = 0; i < count; i++) 8527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert hashcode = hashcode * 37 + digits[i]; 8537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return hashcode; 8557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert 8577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert public String toString() 8587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert { 8597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert if (isZero()) return "0"; 8607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert StringBuilder buf = new StringBuilder("0."); 8617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert for (int i=0; i<count; ++i) buf.append((char)digits[i]); 8627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buf.append("x10^"); 8637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert buf.append(decimalAt); 8647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert return buf.toString(); 8657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert } 8667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert ///CLOVER:ON 8677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert} 868