3 *******************************************************************************
4 * Copyright (C) 1996-2009, International Business Machines Corporation and *
5 * others. All Rights Reserved. *
6 *******************************************************************************
8 package com.ibm.icu.text;
10 import java.math.BigInteger;
13 * <code>DigitList</code> handles the transcoding between numeric values and
14 * strings of characters. It only represents non-negative numbers. The
15 * division of labor between <code>DigitList</code> and
16 * <code>DecimalFormat</code> is that <code>DigitList</code> handles the radix
17 * 10 representation issues and numeric conversion, including rounding;
18 * <code>DecimalFormat</code> handles the locale-specific issues such as
19 * positive and negative representation, digit grouping, decimal point,
20 * currency, and so on.
22 * <p>A <code>DigitList</code> is a representation of a finite numeric value.
23 * <code>DigitList</code> objects do not represent <code>NaN</code> or infinite
24 * values. A <code>DigitList</code> value can be converted to a
25 * <code>BigDecimal</code> without loss of precision. Conversion to other
26 * numeric formats may involve loss of precision, depending on the specific
29 * <p>The <code>DigitList</code> representation consists of a string of
30 * characters, which are the digits radix 10, from '0' to '9'. It also has a
31 * base 10 exponent associated with it. The value represented by a
32 * <code>DigitList</code> object can be computed by mulitplying the fraction
33 * <em>f</em>, where 0 <= <em>f</em> < 1, derived by placing all the digits of
34 * the list to the right of the decimal point, by 10^exponent.
36 * @see java.util.Locale
37 * @see java.text.Format
40 * @see java.text.ChoiceFormat
41 * @see java.text.MessageFormat
42 * @version 1.18 08/12/98
43 * @author Mark Davis, Alan Liu
45 final class DigitList {
47 * The maximum number of significant digits in an IEEE 754 double, that
48 * is, in a Java double. This must not be increased, or garbage digits
49 * will be generated, and should not be decreased, or accuracy will be lost.
51 public static final int MAX_LONG_DIGITS = 19; // == Long.toString(Long.MAX_VALUE).length()
52 public static final int DBL_DIG = 17;
55 * These data members are intentionally public and can be set directly.
57 * The value represented is given by placing the decimal point before
58 * digits[decimalAt]. If decimalAt is < 0, then leading zeros between
59 * the decimal point and the first nonzero digit are implied. If decimalAt
60 * is > count, then trailing zeros between the digits[count-1] and the
61 * decimal point are implied.
63 * Equivalently, the represented value is given by f * 10^decimalAt. Here
64 * f is a value 0.1 <= f < 1 arrived at by placing the digits in Digits to
65 * the right of the decimal.
67 * DigitList is normalized, so if it is non-zero, figits[0] is non-zero. We
68 * don't allow denormalized numbers because our exponent is effectively of
69 * unlimited magnitude. The count value contains the number of significant
70 * digits present in digits[].
72 * Zero is represented by any DigitList with count == 0 or with each digits[i]
73 * for all i <= count == '0'.
75 public int decimalAt = 0;
77 public byte[] digits = new byte[MAX_LONG_DIGITS];
79 private final void ensureCapacity(int digitCapacity, int digitsToCopy) {
80 if (digitCapacity > digits.length) {
81 byte[] newDigits = new byte[digitCapacity * 2];
82 System.arraycopy(digits, 0, newDigits, 0, digitsToCopy);
88 * Return true if the represented number is zero.
92 for (int i=0; i<count; ++i) if (digits[i] != '0') return false;
96 // Unused as of ICU 2.6 - alan
98 // * Clears out the digits.
99 // * Use before appending them.
100 // * Typically, you set a series of digits with append, then at the point
101 // * you hit the decimal point, you set myDigitList.decimalAt = myDigitList.count;
102 // * then go on appending digits.
104 // public void clear () {
110 * Appends digits to the list.
112 public void append (int digit) {
113 ensureCapacity(count+1, count);
114 digits[count++] = (byte) digit;
117 * Utility routine to get the value of the digit list
118 * If (count == 0) this throws a NumberFormatException, which
119 * mimics Long.parseLong().
121 public final double getDouble() {
122 if (count == 0) return 0.0;
123 StringBuffer temp = new StringBuffer(count);
125 for (int i = 0; i < count; ++i) temp.append((char)(digits[i]));
127 temp.append(Integer.toString(decimalAt));
128 return Double.valueOf(temp.toString()).doubleValue();
129 // long value = Long.parseLong(temp.toString());
130 // return (value * Math.pow(10, decimalAt - count));
134 * Utility routine to get the value of the digit list.
135 * If (count == 0) this returns 0, unlike Long.parseLong().
137 public final long getLong() {
138 // for now, simple implementation; later, do proper IEEE native stuff
140 if (count == 0) return 0;
142 // We have to check for this, because this is the one NEGATIVE value
143 // we represent. If we tried to just pass the digits off to parseLong,
144 // we'd get a parse failure.
145 if (isLongMIN_VALUE()) return Long.MIN_VALUE;
147 StringBuffer temp = new StringBuffer(count);
148 for (int i = 0; i < decimalAt; ++i)
150 temp.append((i < count) ? (char)(digits[i]) : '0');
152 return Long.parseLong(temp.toString());
156 * Return a <code>BigInteger</code> representing the value stored in this
157 * <code>DigitList</code>. This method assumes that this object contains
158 * an integral value; if not, it will return an incorrect value.
160 * @param isPositive determines the sign of the returned result
161 * @return the value of this object as a <code>BigInteger</code>
163 public BigInteger getBigInteger(boolean isPositive) {
164 if (isZero()) return BigInteger.valueOf(0);
166 StringBuffer stringRep = new StringBuffer(count);
168 stringRep.append('-');
170 for (int i=0; i<count; ++i) {
171 stringRep.append((char) digits[i]);
174 while (d-- > count) {
175 stringRep.append('0');
177 return new BigInteger(stringRep.toString());
179 int len = decimalAt > count ? decimalAt : count;
183 char[] text = new char[len];
187 for (int i = 0; i < count; ++i) {
188 text[i+1] = (char)digits[i];
192 for (int i = 0; i < count; ++i) {
193 text[i] = (char)digits[i];
197 for (int i = n; i < text.length; ++i) {
200 return new BigInteger(new String(text));
204 private String getStringRep(boolean isPositive) {
205 if (isZero()) return "0";
206 StringBuffer stringRep = new StringBuffer(count+1);
208 stringRep.append('-');
212 stringRep.append('.');
214 stringRep.append('0');
219 for (int i=0; i<count; ++i) {
221 stringRep.append('.');
223 stringRep.append((char) digits[i]);
225 while (d-- > count) {
226 stringRep.append('0');
228 return stringRep.toString();
231 //#if defined(FOUNDATION10)
234 * Return a <code>BigDecimal</code> representing the value stored in this
235 * <code>DigitList</code>.
237 * @param isPositive determines the sign of the returned result
238 * @return the value of this object as a <code>BigDecimal</code>
240 public java.math.BigDecimal getBigDecimal(boolean isPositive) {
242 return java.math.BigDecimal.valueOf(0);
244 // if exponential notion is negative,
245 // we prefer to use BigDecimal constructor with scale,
246 // because it works better when extremely small value
247 // is used. See #5698.
248 long scale = (long)count - (long)decimalAt;
250 int numDigits = count;
251 if (scale > (long)Integer.MAX_VALUE) {
252 // try to reduce the scale
253 long numShift = scale - (long)Integer.MAX_VALUE;
254 if (numShift < count) {
255 numDigits -= numShift;
258 return new java.math.BigDecimal(0);
261 StringBuffer significantDigits = new StringBuffer(numDigits + 1);
263 significantDigits.append('-');
265 for (int i = 0; i < numDigits; i++) {
266 significantDigits.append((char)digits[i]);
268 BigInteger unscaledVal = new BigInteger(significantDigits.toString());
269 return new java.math.BigDecimal(unscaledVal, (int)scale);
271 // We should be able to use a negative scale value for a positive exponential
272 // value on JDK1.5. But it is not supported by older JDK. So, for now,
273 // we always use BigDecimal constructor which takes String.
274 return new java.math.BigDecimal(getStringRep(isPositive));
280 * Return an <code>ICU BigDecimal</code> representing the value stored in this
281 * <code>DigitList</code>.
283 * @param isPositive determines the sign of the returned result
284 * @return the value of this object as a <code>BigDecimal</code>
286 public com.ibm.icu.math.BigDecimal getBigDecimalICU(boolean isPositive) {
288 return com.ibm.icu.math.BigDecimal.valueOf(0);
290 // if exponential notion is negative,
291 // we prefer to use BigDecimal constructor with scale,
292 // because it works better when extremely small value
293 // is used. See #5698.
294 long scale = (long)count - (long)decimalAt;
296 int numDigits = count;
297 if (scale > (long)Integer.MAX_VALUE) {
298 // try to reduce the scale
299 long numShift = scale - (long)Integer.MAX_VALUE;
300 if (numShift < count) {
301 numDigits -= numShift;
304 return new com.ibm.icu.math.BigDecimal(0);
307 StringBuffer significantDigits = new StringBuffer(numDigits + 1);
309 significantDigits.append('-');
311 for (int i = 0; i < numDigits; i++) {
312 significantDigits.append((char)digits[i]);
314 BigInteger unscaledVal = new BigInteger(significantDigits.toString());
315 return new com.ibm.icu.math.BigDecimal(unscaledVal, (int)scale);
317 return new com.ibm.icu.math.BigDecimal(getStringRep(isPositive));
322 * Return whether or not this objects represented value is an integer.
324 * @return true if the represented value of this object is an integer
326 boolean isIntegral() {
327 // Trim trailing zeros. This does not change the represented value.
328 while (count > 0 && digits[count - 1] == (byte)'0') --count;
329 return count == 0 || decimalAt >= count;
332 // Unused as of ICU 2.6 - alan
334 // * Return true if the number represented by this object can fit into
337 // boolean fitsIntoLong(boolean isPositive)
339 // // Figure out if the result will fit in a long. We have to
340 // // first look for nonzero digits after the decimal point;
341 // // then check the size. If the digit count is 18 or less, then
342 // // the value can definitely be represented as a long. If it is 19
343 // // then it may be too large.
345 // // Trim trailing zeros. This does not change the represented value.
346 // while (count > 0 && digits[count - 1] == (byte)'0') --count;
349 // // Positive zero fits into a long, but negative zero can only
350 // // be represented as a double. - bug 4162852
351 // return isPositive;
354 // if (decimalAt < count || decimalAt > MAX_LONG_DIGITS) return false;
356 // if (decimalAt < MAX_LONG_DIGITS) return true;
358 // // At this point we have decimalAt == count, and count == MAX_LONG_DIGITS.
359 // // The number will overflow if it is larger than 9223372036854775807
360 // // or smaller than -9223372036854775808.
361 // for (int i=0; i<count; ++i)
363 // byte dig = digits[i], max = LONG_MIN_REP[i];
364 // if (dig > max) return false;
365 // if (dig < max) return true;
368 // // At this point the first count digits match. If decimalAt is less
369 // // than count, then the remaining digits are zero, and we return true.
370 // if (count < decimalAt) return true;
372 // // Now we have a representation of Long.MIN_VALUE, without the leading
373 // // negative sign. If this represents a positive value, then it does
374 // // not fit; otherwise it fits.
375 // return !isPositive;
378 // Unused as of ICU 2.6 - alan
380 // * Set the digit list to a representation of the given double value.
381 // * This method supports fixed-point notation.
382 // * @param source Value to be converted; must not be Inf, -Inf, Nan,
383 // * or a value <= 0.
384 // * @param maximumFractionDigits The most fractional digits which should
387 // public final void set(double source, int maximumFractionDigits)
389 // set(source, maximumFractionDigits, true);
393 * Set the digit list to a representation of the given double value.
394 * This method supports both fixed-point and exponential notation.
395 * @param source Value to be converted; must not be Inf, -Inf, Nan,
397 * @param maximumDigits The most fractional or total digits which should
399 * @param fixedPoint If true, then maximumDigits is the maximum
400 * fractional digits to be converted. If false, total digits.
402 final void set(double source, int maximumDigits, boolean fixedPoint)
404 if (source == 0) source = 0;
405 // Generate a representation of the form DDDDD, DDDDD.DDDDD, or
407 String rep = Double.toString(source);
409 set(rep, MAX_LONG_DIGITS);
412 // The negative of the exponent represents the number of leading
413 // zeros between the decimal and the first non-zero digit, for
414 // a value < 0.1 (e.g., for 0.00123, -decimalAt == 2). If this
415 // is more than the maximum fraction digits, then we have an underflow
416 // for the printed representation.
417 if (-decimalAt > maximumDigits) {
420 } else if (-decimalAt == maximumDigits) {
421 if (shouldRoundUp(0)) {
424 digits[0] = (byte)'1';
433 // Eliminate trailing zeros.
434 while (count > 1 && digits[count - 1] == '0')
437 // Eliminate digits beyond maximum digits to be displayed.
438 // Round up if appropriate.
439 round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits);
443 * Given a string representation of the form DDDDD, DDDDD.DDDDD,
444 * or DDDDDE+/-DDDDD, set this object's value to it. Ignore
447 private void set(String rep, int maxCount) {
451 // Number of zeros between decimal point and first non-zero digit after
452 // decimal point, for numbers < 1.
453 int leadingZerosAfterDecimal = 0;
454 boolean nonZeroDigitSeen = false;
455 // Skip over leading '-'
457 if (rep.charAt(i) == '-') {
460 for (; i < rep.length(); ++i) {
461 char c = rep.charAt(i);
464 } else if (c == 'e' || c == 'E') {
466 // Integer.parseInt doesn't handle leading '+' signs
467 if (rep.charAt(i) == '+') {
470 exponent = Integer.valueOf(rep.substring(i)).intValue();
472 } else if (count < maxCount) {
473 if (!nonZeroDigitSeen) {
474 nonZeroDigitSeen = (c != '0');
475 if (!nonZeroDigitSeen && decimalAt != -1) {
476 ++leadingZerosAfterDecimal;
480 if (nonZeroDigitSeen) {
481 ensureCapacity(count+1, count);
482 digits[count++] = (byte)c;
486 if (decimalAt == -1) {
489 decimalAt += exponent - leadingZerosAfterDecimal;
493 * Return true if truncating the representation to the given number
494 * of digits will result in an increment to the last digit. This
495 * method implements half-even rounding, the default rounding mode.
497 * @param maximumDigits the number of digits to keep, from 0 to
498 * <code>count-1</code>. If 0, then all digits are rounded away, and
499 * this method returns true if a one should be generated (e.g., formatting
501 * @return true if digit <code>maximumDigits-1</code> should be
504 private boolean shouldRoundUp(int maximumDigits) {
505 // variable not used boolean increment = false;
506 // Implement IEEE half-even rounding
508 format(0.0) gives "0.1" if preceded by parse("99.99") [Richard/GCL]
510 if (maximumDigits < count) {
511 if (digits[maximumDigits] > '5') {
513 } else if (digits[maximumDigits] == '5' ) {
514 for (int i=maximumDigits+1; i<count; ++i) {
515 if (digits[i] != '0') {
519 return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0);
526 * Round the representation to the given number of digits.
527 * @param maximumDigits The maximum number of digits to be shown.
528 * Upon return, count will be less than or equal to maximumDigits.
529 * This now performs rounding when maximumDigits is 0, formerly it did not.
531 public final void round(int maximumDigits) {
532 // Eliminate digits beyond maximum digits to be displayed.
533 // Round up if appropriate.
534 // [bnf] rewritten to fix 4179818
535 if (maximumDigits >= 0 && maximumDigits < count) {
536 if (shouldRoundUp(maximumDigits)) {
537 // Rounding up involves incrementing digits from LSD to MSD.
538 // In most cases this is simple, but in a worst case situation
539 // (9999..99) we have to adjust the decimalAt value.
543 if (maximumDigits < 0)
545 // We have all 9's, so we increment to a single digit
546 // of one and adjust the exponent.
547 digits[0] = (byte) '1';
549 maximumDigits = 0; // Adjust the count
553 ++digits[maximumDigits];
554 if (digits[maximumDigits] <= '9') break;
555 // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this
557 ++maximumDigits; // Increment for use as count
559 count = maximumDigits;
560 /*Bug 4217661 DecimalFormat formats 1.001 to "1.00" instead of "1"
561 Eliminate trailing zeros. [Richard/GCL]
563 while (count > 1 && digits[count-1] == '0') {
570 * Utility routine to set the value of the digit list from a long
572 public final void set(long source)
578 * Set the digit list to a representation of the given long value.
579 * @param source Value to be converted; must be >= 0 or ==
581 * @param maximumDigits The most digits which should be converted.
582 * If maximumDigits is lower than the number of significant digits
583 * in source, the representation will be rounded. Ignored if <= 0.
585 public final void set(long source, int maximumDigits)
587 // This method does not expect a negative number. However,
588 // "source" can be a Long.MIN_VALUE (-9223372036854775808),
589 // if the number being formatted is a Long.MIN_VALUE. In that
590 // case, it will be formatted as -Long.MIN_VALUE, a number
591 // which is outside the legal range of a long, but which can
592 // be represented by DigitList.
593 // [NEW] Faster implementation
595 if (source == Long.MIN_VALUE) {
596 decimalAt = count = MAX_LONG_DIGITS;
597 System.arraycopy(LONG_MIN_REP, 0, digits, 0, count);
603 int left = MAX_LONG_DIGITS;
606 digits[--left] = (byte) (((long) '0') + (source % 10));
609 decimalAt = MAX_LONG_DIGITS-left;
610 // Don't copy trailing zeros
611 // we are guaranteed that there is at least one non-zero digit,
612 // so we don't have to check lower bounds
613 for (right = MAX_LONG_DIGITS - 1; digits[right] == (byte) '0'; --right) {}
614 count = right - left + 1;
615 System.arraycopy(digits, left, digits, 0, count);
617 if (maximumDigits > 0) round(maximumDigits);
621 * Set the digit list to a representation of the given BigInteger value.
623 * @param source Value to be converted
624 * @param maximumDigits The most digits which should be converted.
625 * If maximumDigits is lower than the number of significant digits
626 * in source, the representation will be rounded. Ignored if <= 0.
628 public final void set(BigInteger source, int maximumDigits) {
629 String stringDigits = source.toString();
631 count = decimalAt = stringDigits.length();
633 // Don't copy trailing zeros
634 while (count > 1 && stringDigits.charAt(count - 1) == '0') --count;
637 if (stringDigits.charAt(0) == '-') {
643 ensureCapacity(count, 0);
644 for (int i = 0; i < count; ++i) {
645 digits[i] = (byte) stringDigits.charAt(i + offset);
648 if (maximumDigits > 0) round(maximumDigits);
652 * Internal method that sets this digit list to represent the
653 * given value. The value is given as a String of the format
654 * returned by BigDecimal.
655 * @param stringDigits value to be represented with the following
656 * syntax, expressed as a regular expression: -?\d*.?\d*
657 * Must not be an empty string.
658 * @param maximumDigits The most digits which should be converted.
659 * If maximumDigits is lower than the number of significant digits
660 * in source, the representation will be rounded. Ignored if <= 0.
661 * @param fixedPoint If true, then maximumDigits is the maximum
662 * fractional digits to be converted. If false, total digits.
664 private void setBigDecimalDigits(String stringDigits,
665 int maximumDigits, boolean fixedPoint) {
666 //| // Find the first non-zero digit, the decimal, and the last non-zero digit.
667 //| int first=-1, last=stringDigits.length()-1, decimal=-1;
668 //| for (int i=0; (first<0 || decimal<0) && i<=last; ++i) {
669 //| char c = stringDigits.charAt(i);
672 //| } else if (first < 0 && (c >= '1' && c <= '9')) {
682 //| // At this point we know there is at least one non-zero digit, so the
683 //| // following loop is safe.
685 //| char c = stringDigits.charAt(last);
686 //| if (c != '0' && c != '.') {
692 //| if (decimal < 0) {
693 //| decimal = stringDigits.length();
696 //| count = last - first;
697 //| if (decimal < first || decimal > last) {
700 //| decimalAt = decimal - first;
701 //| if (decimalAt < 0) {
705 //| ensureCapacity(count, 0);
706 //| for (int i = 0; i < count; ++i) {
707 //| digits[i] = (byte) stringDigits.charAt(first++);
708 //| if (first == decimal) {
713 // The maxDigits here could also be Integer.MAX_VALUE
714 set(stringDigits, stringDigits.length());
716 // Eliminate digits beyond maximum digits to be displayed.
717 // Round up if appropriate.
718 // {dlf} Some callers depend on passing '0' to round to mean 'don't round', but
719 // rather than pass that information explicitly, we rely on some magic with maximumDigits
720 // and decimalAt. Unfortunately, this is no good, because there are cases where maximumDigits
721 // is zero and we do want to round, e.g. BigDecimal values -1 < x < 1. So since round
722 // changed to perform rounding when the argument is 0, we now force the argument
723 // to -1 in the situations where it matters.
724 round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits);
727 //#if defined(FOUNDATION10)
730 * Set the digit list to a representation of the given BigDecimal value.
732 * @param source Value to be converted
733 * @param maximumDigits The most digits which should be converted.
734 * If maximumDigits is lower than the number of significant digits
735 * in source, the representation will be rounded. Ignored if <= 0.
736 * @param fixedPoint If true, then maximumDigits is the maximum
737 * fractional digits to be converted. If false, total digits.
739 public final void set(java.math.BigDecimal source,
740 int maximumDigits, boolean fixedPoint) {
741 setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint);
746 * Set the digit list to a representation of the given BigDecimal value.
748 * @param source Value to be converted
749 * @param maximumDigits The most digits which should be converted.
750 * If maximumDigits is lower than the number of significant digits
751 * in source, the representation will be rounded. Ignored if <= 0.
752 * @param fixedPoint If true, then maximumDigits is the maximum
753 * fractional digits to be converted. If false, total digits.
755 public final void set(com.ibm.icu.math.BigDecimal source,
756 int maximumDigits, boolean fixedPoint) {
757 setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint);
761 * Returns true if this DigitList represents Long.MIN_VALUE;
762 * false, otherwise. This is required so that getLong() works.
764 private boolean isLongMIN_VALUE()
766 if (decimalAt != count || count != MAX_LONG_DIGITS)
769 for (int i = 0; i < count; ++i)
771 if (digits[i] != LONG_MIN_REP[i]) return false;
777 private static byte[] LONG_MIN_REP;
781 // Store the representation of LONG_MIN without the leading '-'
782 String s = Long.toString(Long.MIN_VALUE);
783 LONG_MIN_REP = new byte[MAX_LONG_DIGITS];
784 for (int i=0; i < MAX_LONG_DIGITS; ++i)
786 LONG_MIN_REP[i] = (byte)s.charAt(i + 1);
790 // Unused -- Alan 2003-05
792 // * Return the floor of the log base 10 of a given double.
793 // * This method compensates for inaccuracies which arise naturally when
794 // * computing logs, and always give the correct value. The parameter
795 // * must be positive and finite.
797 // private static final int log10(double d)
799 // // The reason this routine is needed is that simply taking the
800 // // log and dividing by log10 yields a result which may be off
801 // // by 1 due to rounding errors. For example, the naive log10
802 // // of 1.0e300 taken this way is 299, rather than 300.
803 // double log10 = Math.log(d) / LOG10;
804 // int ilog10 = (int)Math.floor(log10);
805 // // Positive logs could be too small, e.g. 0.99 instead of 1.0
806 // if (log10 > 0 && d >= Math.pow(10, ilog10 + 1))
810 // // Negative logs could be too big, e.g. -0.99 instead of -1.0
811 // else if (log10 < 0 && d < Math.pow(10, ilog10))
818 // private static final double LOG10 = Math.log(10.0);
820 // (The following boilerplate methods are currently not called,
821 // and cannot be called by tests since this class is
822 // package-private. The methods may be useful in the future, so
823 // we do not delete them. 2003-06-11 ICU 2.6 Alan)
826 * equality test between two digit lists.
828 public boolean equals(Object obj) {
829 if (this == obj) // quick check
831 if (!(obj instanceof DigitList)) // (1) same object?
833 DigitList other = (DigitList) obj;
834 if (count != other.count ||
835 decimalAt != other.decimalAt)
837 for (int i = 0; i < count; i++)
838 if (digits[i] != other.digits[i])
844 * Generates the hash code for the digit list.
846 public int hashCode() {
847 int hashcode = decimalAt;
849 for (int i = 0; i < count; i++)
850 hashcode = hashcode * 37 + digits[i];
855 public String toString()
857 if (isZero()) return "0";
858 StringBuffer buf = new StringBuffer("0.");
859 for (int i=0; i<count; ++i) buf.append((char)digits[i]);
861 buf.append(decimalAt);
862 return buf.toString();