KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibm > icu > text > DigitList


1 //##header 1189099963000 FOUNDATION
2
/*
3  *******************************************************************************
4  * Copyright (C) 1996-2005, International Business Machines Corporation and *
5  * others. All Rights Reserved. *
6  *******************************************************************************
7  */

8 package com.ibm.icu.text;
9
10 import java.math.BigInteger JavaDoc;
11
12 /**
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.
21  *
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
27  * value.
28  *
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.
35  *
36  * @see java.util.Locale
37  * @see java.text.Format
38  * @see NumberFormat
39  * @see DecimalFormat
40  * @see java.text.ChoiceFormat
41  * @see java.text.MessageFormat
42  * @version 1.18 08/12/98
43  * @author Mark Davis, Alan Liu
44  * */

45 final class DigitList {
46     /**
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.
50      */

51     public static final int MAX_LONG_DIGITS = 19; // == Long.toString(Long.MAX_VALUE).length()
52
public static final int DBL_DIG = 17;
53
54     /**
55      * These data members are intentionally public and can be set directly.
56      *
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.
62      *
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.
66      *
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[].
71      *
72      * Zero is represented by any DigitList with count == 0 or with each digits[i]
73      * for all i <= count == '0'.
74      */

75     public int decimalAt = 0;
76     public int count = 0;
77     public byte[] digits = new byte[MAX_LONG_DIGITS];
78
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);
83             digits = newDigits;
84         }
85     }
86
87     /**
88      * Return true if the represented number is zero.
89      */

90     boolean isZero()
91     {
92         for (int i=0; i<count; ++i) if (digits[i] != '0') return false;
93         return true;
94     }
95
96 // Unused as of ICU 2.6 - alan
97
// /**
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.
103
// */
104
// public void clear () {
105
// decimalAt = 0;
106
// count = 0;
107
// }
108

109     /**
110      * Appends digits to the list.
111      */

112     public void append (int digit) {
113         ensureCapacity(count+1, count);
114         digits[count++] = (byte) digit;
115     }
116     /**
117      * Utility routine to get the value of the digit list
118      * If (count == 0) this throws a NumberFormatException, which
119      * mimics Long.parseLong().
120      */

121     public final double getDouble() {
122         if (count == 0) return 0.0;
123         StringBuffer JavaDoc temp = new StringBuffer JavaDoc(count);
124         temp.append('.');
125         for (int i = 0; i < count; ++i) temp.append((char)(digits[i]));
126         temp.append('E');
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));
131
}
132
133     /**
134      * Utility routine to get the value of the digit list.
135      * If (count == 0) this returns 0, unlike Long.parseLong().
136      */

137     public final long getLong() {
138         // for now, simple implementation; later, do proper IEEE native stuff
139

140         if (count == 0) return 0;
141
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;
146
147         StringBuffer JavaDoc temp = new StringBuffer JavaDoc(count);
148         for (int i = 0; i < decimalAt; ++i)
149         {
150             temp.append((i < count) ? (char)(digits[i]) : '0');
151         }
152         return Long.parseLong(temp.toString());
153     }
154
155     /**
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.
159      * [bnf]
160      * @param isPositive determines the sign of the returned result
161      * @return the value of this object as a <code>BigInteger</code>
162      */

163     public BigInteger JavaDoc getBigInteger(boolean isPositive) {
164         if (isZero()) return BigInteger.valueOf(0);
165         if (false) {
166             StringBuffer JavaDoc stringRep = new StringBuffer JavaDoc(count);
167             if (!isPositive) {
168                 stringRep.append('-');
169             }
170             for (int i=0; i<count; ++i) {
171                 stringRep.append((char) digits[i]);
172             }
173             int d = decimalAt;
174             while (d-- > count) {
175                 stringRep.append('0');
176             }
177             return new BigInteger JavaDoc(stringRep.toString());
178         } else {
179             int len = decimalAt > count ? decimalAt : count;
180             if (!isPositive) {
181                 len += 1;
182             }
183             char[] text = new char[len];
184             int n = 0;
185             if (!isPositive) {
186                 text[0] = '-';
187                 for (int i = 0; i < count; ++i) {
188                     text[i+1] = (char)digits[i];
189                 }
190                 n = count+1;
191             } else {
192                 for (int i = 0; i < count; ++i) {
193                     text[i] = (char)digits[i];
194                 }
195                 n = count;
196             }
197             for (int i = n; i < text.length; ++i) {
198                 text[i] = '0';
199             }
200             return new BigInteger JavaDoc(new String JavaDoc(text));
201         }
202     }
203
204     private String JavaDoc getStringRep(boolean isPositive) {
205         if (isZero()) return "0";
206         StringBuffer JavaDoc stringRep = new StringBuffer JavaDoc(count+1);
207         if (!isPositive) {
208             stringRep.append('-');
209         }
210         int d = decimalAt;
211         if (d < 0) {
212             stringRep.append('.');
213             while (d < 0) {
214                 stringRep.append('0');
215                 ++d;
216             }
217             d = -1;
218         }
219         for (int i=0; i<count; ++i) {
220             if (d == i) {
221                 stringRep.append('.');
222             }
223             stringRep.append((char) digits[i]);
224         }
225         while (d-- > count) {
226             stringRep.append('0');
227         }
228         return stringRep.toString();
229     }
230     
231 //#ifndef FOUNDATION
232
//## /**
233
//## * Return a <code>BigDecimal</code> representing the value stored in this
234
//## * <code>DigitList</code>.
235
//## * [bnf]
236
//## * @param isPositive determines the sign of the returned result
237
//## * @return the value of this object as a <code>BigDecimal</code>
238
//## */
239
//## public java.math.BigDecimal getBigDecimal(boolean isPositive) {
240
//## if (isZero()) return java.math.BigDecimal.valueOf(0);
241
//## return new java.math.BigDecimal(getStringRep(isPositive));
242
//## }
243
//#endif
244

245     /**
246      * Return an <code>ICU BigDecimal</code> representing the value stored in this
247      * <code>DigitList</code>.
248      * [bnf]
249      * @param isPositive determines the sign of the returned result
250      * @return the value of this object as a <code>BigDecimal</code>
251      */

252     public com.ibm.icu.math.BigDecimal getBigDecimalICU(boolean isPositive) {
253         if (isZero()) return com.ibm.icu.math.BigDecimal.valueOf(0);
254        return new com.ibm.icu.math.BigDecimal(getStringRep(isPositive));
255     }
256
257     /**
258      * Return whether or not this objects represented value is an integer.
259      * [bnf]
260      * @return true if the represented value of this object is an integer
261      */

262     boolean isIntegral() {
263         // Trim trailing zeros. This does not change the represented value.
264
while (count > 0 && digits[count - 1] == (byte)'0') --count;
265         return count == 0 || decimalAt >= count;
266     }
267
268 // Unused as of ICU 2.6 - alan
269
// /**
270
// * Return true if the number represented by this object can fit into
271
// * a long.
272
// */
273
// boolean fitsIntoLong(boolean isPositive)
274
// {
275
// // Figure out if the result will fit in a long. We have to
276
// // first look for nonzero digits after the decimal point;
277
// // then check the size. If the digit count is 18 or less, then
278
// // the value can definitely be represented as a long. If it is 19
279
// // then it may be too large.
280
//
281
// // Trim trailing zeros. This does not change the represented value.
282
// while (count > 0 && digits[count - 1] == (byte)'0') --count;
283
//
284
// if (count == 0) {
285
// // Positive zero fits into a long, but negative zero can only
286
// // be represented as a double. - bug 4162852
287
// return isPositive;
288
// }
289
//
290
// if (decimalAt < count || decimalAt > MAX_LONG_DIGITS) return false;
291
//
292
// if (decimalAt < MAX_LONG_DIGITS) return true;
293
//
294
// // At this point we have decimalAt == count, and count == MAX_LONG_DIGITS.
295
// // The number will overflow if it is larger than 9223372036854775807
296
// // or smaller than -9223372036854775808.
297
// for (int i=0; i<count; ++i)
298
// {
299
// byte dig = digits[i], max = LONG_MIN_REP[i];
300
// if (dig > max) return false;
301
// if (dig < max) return true;
302
// }
303
//
304
// // At this point the first count digits match. If decimalAt is less
305
// // than count, then the remaining digits are zero, and we return true.
306
// if (count < decimalAt) return true;
307
//
308
// // Now we have a representation of Long.MIN_VALUE, without the leading
309
// // negative sign. If this represents a positive value, then it does
310
// // not fit; otherwise it fits.
311
// return !isPositive;
312
// }
313

314 // Unused as of ICU 2.6 - alan
315
// /**
316
// * Set the digit list to a representation of the given double value.
317
// * This method supports fixed-point notation.
318
// * @param source Value to be converted; must not be Inf, -Inf, Nan,
319
// * or a value <= 0.
320
// * @param maximumFractionDigits The most fractional digits which should
321
// * be converted.
322
// */
323
// public final void set(double source, int maximumFractionDigits)
324
// {
325
// set(source, maximumFractionDigits, true);
326
// }
327

328     /**
329      * Set the digit list to a representation of the given double value.
330      * This method supports both fixed-point and exponential notation.
331      * @param source Value to be converted; must not be Inf, -Inf, Nan,
332      * or a value <= 0.
333      * @param maximumDigits The most fractional or total digits which should
334      * be converted.
335      * @param fixedPoint If true, then maximumDigits is the maximum
336      * fractional digits to be converted. If false, total digits.
337      */

338     final void set(double source, int maximumDigits, boolean fixedPoint)
339     {
340         if (source == 0) source = 0;
341         // Generate a representation of the form DDDDD, DDDDD.DDDDD, or
342
// DDDDDE+/-DDDDD.
343
String JavaDoc rep = Double.toString(source);
344
345         set(rep, MAX_LONG_DIGITS);
346
347         if (fixedPoint) {
348             // The negative of the exponent represents the number of leading
349
// zeros between the decimal and the first non-zero digit, for
350
// a value < 0.1 (e.g., for 0.00123, -decimalAt == 2). If this
351
// is more than the maximum fraction digits, then we have an underflow
352
// for the printed representation.
353
if (-decimalAt > maximumDigits) {
354                 count = 0;
355                 return;
356             } else if (-decimalAt == maximumDigits) {
357                 if (shouldRoundUp(0)) {
358                     count = 1;
359                     ++decimalAt;
360                     digits[0] = (byte)'1';
361                 } else {
362                     count = 0;
363                 }
364                 return;
365             }
366             // else fall through
367
}
368
369         // Eliminate trailing zeros.
370
while (count > 1 && digits[count - 1] == '0')
371             --count;
372
373         // Eliminate digits beyond maximum digits to be displayed.
374
// Round up if appropriate.
375
round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits);
376     }
377
378     /**
379      * Given a string representation of the form DDDDD, DDDDD.DDDDD,
380      * or DDDDDE+/-DDDDD, set this object's value to it. Ignore
381      * any leading '-'.
382      */

383     private void set(String JavaDoc rep, int maxCount) {
384         decimalAt = -1;
385         count = 0;
386         int exponent = 0;
387         // Number of zeros between decimal point and first non-zero digit after
388
// decimal point, for numbers < 1.
389
int leadingZerosAfterDecimal = 0;
390         boolean nonZeroDigitSeen = false;
391         // Skip over leading '-'
392
int i=0;
393         if (rep.charAt(i) == '-') {
394             ++i;
395         }
396         for (; i < rep.length(); ++i) {
397             char c = rep.charAt(i);
398             if (c == '.') {
399                 decimalAt = count;
400             } else if (c == 'e' || c == 'E') {
401                 ++i;
402                 // Integer.parseInt doesn't handle leading '+' signs
403
if (rep.charAt(i) == '+') {
404                     ++i;
405                 }
406                 exponent = Integer.valueOf(rep.substring(i)).intValue();
407                 break;
408             } else if (count < maxCount) {
409                 if (!nonZeroDigitSeen) {
410                     nonZeroDigitSeen = (c != '0');
411                     if (!nonZeroDigitSeen && decimalAt != -1) {
412                         ++leadingZerosAfterDecimal;
413                     }
414                 }
415
416                 if (nonZeroDigitSeen) {
417                     ensureCapacity(count+1, count);
418                     digits[count++] = (byte)c;
419                 }
420             }
421         }
422         if (decimalAt == -1) {
423             decimalAt = count;
424         }
425         decimalAt += exponent - leadingZerosAfterDecimal;
426     }
427
428     /**
429      * Return true if truncating the representation to the given number
430      * of digits will result in an increment to the last digit. This
431      * method implements half-even rounding, the default rounding mode.
432      * [bnf]
433      * @param maximumDigits the number of digits to keep, from 0 to
434      * <code>count-1</code>. If 0, then all digits are rounded away, and
435      * this method returns true if a one should be generated (e.g., formatting
436      * 0.09 with "#.#").
437      * @return true if digit <code>maximumDigits-1</code> should be
438      * incremented
439      */

440     private boolean shouldRoundUp(int maximumDigits) {
441         // variable not used boolean increment = false;
442
// Implement IEEE half-even rounding
443
/*Bug 4243108
444           format(0.0) gives "0.1" if preceded by parse("99.99") [Richard/GCL]
445         */

446         if (maximumDigits < count) {
447             if (digits[maximumDigits] > '5') {
448                 return true;
449             } else if (digits[maximumDigits] == '5' ) {
450                 for (int i=maximumDigits+1; i<count; ++i) {
451                     if (digits[i] != '0') {
452                         return true;
453                     }
454                 }
455                 return maximumDigits > 0 && (digits[maximumDigits-1] % 2 != 0);
456             }
457         }
458         return false;
459     }
460
461     /**
462      * Round the representation to the given number of digits.
463      * @param maximumDigits The maximum number of digits to be shown.
464      * Upon return, count will be less than or equal to maximumDigits.
465      * This now performs rounding when maximumDigits is 0, formerly it did not.
466      */

467     public final void round(int maximumDigits) {
468         // Eliminate digits beyond maximum digits to be displayed.
469
// Round up if appropriate.
470
// [bnf] rewritten to fix 4179818
471
if (maximumDigits >= 0 && maximumDigits < count) {
472             if (shouldRoundUp(maximumDigits)) {
473                 // Rounding up involves incrementing digits from LSD to MSD.
474
// In most cases this is simple, but in a worst case situation
475
// (9999..99) we have to adjust the decimalAt value.
476
for (;;)
477                 {
478                     --maximumDigits;
479                     if (maximumDigits < 0)
480                     {
481                         // We have all 9's, so we increment to a single digit
482
// of one and adjust the exponent.
483
digits[0] = (byte) '1';
484                         ++decimalAt;
485                         maximumDigits = 0; // Adjust the count
486
break;
487                     }
488
489                     ++digits[maximumDigits];
490                     if (digits[maximumDigits] <= '9') break;
491                     // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this
492
}
493                 ++maximumDigits; // Increment for use as count
494
}
495             count = maximumDigits;
496             /*Bug 4217661 DecimalFormat formats 1.001 to "1.00" instead of "1"
497               Eliminate trailing zeros. [Richard/GCL]
498             */

499             while (count > 1 && digits[count-1] == '0') {
500                 --count;
501             } //[Richard/GCL]
502
}
503     }
504
505     /**
506      * Utility routine to set the value of the digit list from a long
507      */

508     public final void set(long source)
509     {
510         set(source, 0);
511     }
512
513     /**
514      * Set the digit list to a representation of the given long value.
515      * @param source Value to be converted; must be >= 0 or ==
516      * Long.MIN_VALUE.
517      * @param maximumDigits The most digits which should be converted.
518      * If maximumDigits is lower than the number of significant digits
519      * in source, the representation will be rounded. Ignored if <= 0.
520      */

521     public final void set(long source, int maximumDigits)
522     {
523         // This method does not expect a negative number. However,
524
// "source" can be a Long.MIN_VALUE (-9223372036854775808),
525
// if the number being formatted is a Long.MIN_VALUE. In that
526
// case, it will be formatted as -Long.MIN_VALUE, a number
527
// which is outside the legal range of a long, but which can
528
// be represented by DigitList.
529
// [NEW] Faster implementation
530
if (source <= 0) {
531             if (source == Long.MIN_VALUE) {
532                 decimalAt = count = MAX_LONG_DIGITS;
533                 System.arraycopy(LONG_MIN_REP, 0, digits, 0, count);
534             } else {
535                 count = 0;
536                 decimalAt = 0;
537             }
538         } else {
539             int left = MAX_LONG_DIGITS;
540             int right;
541             while (source > 0) {
542                 digits[--left] = (byte) (((long) '0') + (source % 10));
543                 source /= 10;
544             }
545             decimalAt = MAX_LONG_DIGITS-left;
546             // Don't copy trailing zeros
547
// we are guaranteed that there is at least one non-zero digit,
548
// so we don't have to check lower bounds
549
for (right = MAX_LONG_DIGITS - 1; digits[right] == (byte) '0'; --right) {}
550             count = right - left + 1;
551             System.arraycopy(digits, left, digits, 0, count);
552         }
553         if (maximumDigits > 0) round(maximumDigits);
554     }
555
556     /**
557      * Set the digit list to a representation of the given BigInteger value.
558      * [bnf]
559      * @param source Value to be converted
560      * @param maximumDigits The most digits which should be converted.
561      * If maximumDigits is lower than the number of significant digits
562      * in source, the representation will be rounded. Ignored if <= 0.
563      */

564     public final void set(BigInteger JavaDoc source, int maximumDigits) {
565         String JavaDoc stringDigits = source.toString();
566
567         count = decimalAt = stringDigits.length();
568
569         // Don't copy trailing zeros
570
while (count > 1 && stringDigits.charAt(count - 1) == '0') --count;
571
572         int offset = 0;
573         if (stringDigits.charAt(0) == '-') {
574             ++offset;
575             --count;
576             --decimalAt;
577         }
578
579         ensureCapacity(count, 0);
580         for (int i = 0; i < count; ++i) {
581             digits[i] = (byte) stringDigits.charAt(i + offset);
582         }
583
584         if (maximumDigits > 0) round(maximumDigits);
585     }
586
587     /**
588      * Internal method that sets this digit list to represent the
589      * given value. The value is given as a String of the format
590      * returned by BigDecimal.
591      * @param stringDigits value to be represented with the following
592      * syntax, expressed as a regular expression: -?\d*.?\d*
593      * Must not be an empty string.
594      * @param maximumDigits The most digits which should be converted.
595      * If maximumDigits is lower than the number of significant digits
596      * in source, the representation will be rounded. Ignored if <= 0.
597      * @param fixedPoint If true, then maximumDigits is the maximum
598      * fractional digits to be converted. If false, total digits.
599      */

600     private void setBigDecimalDigits(String JavaDoc stringDigits,
601                                      int maximumDigits, boolean fixedPoint) {
602 //| // Find the first non-zero digit, the decimal, and the last non-zero digit.
603
//| int first=-1, last=stringDigits.length()-1, decimal=-1;
604
//| for (int i=0; (first<0 || decimal<0) && i<=last; ++i) {
605
//| char c = stringDigits.charAt(i);
606
//| if (c == '.') {
607
//| decimal = i;
608
//| } else if (first < 0 && (c >= '1' && c <= '9')) {
609
//| first = i;
610
//| }
611
//| }
612
//|
613
//| if (first < 0) {
614
//| clear();
615
//| return;
616
//| }
617
//|
618
//| // At this point we know there is at least one non-zero digit, so the
619
//| // following loop is safe.
620
//| for (;;) {
621
//| char c = stringDigits.charAt(last);
622
//| if (c != '0' && c != '.') {
623
//| break;
624
//| }
625
//| --last;
626
//| }
627
//|
628
//| if (decimal < 0) {
629
//| decimal = stringDigits.length();
630
//| }
631
//|
632
//| count = last - first;
633
//| if (decimal < first || decimal > last) {
634
//| ++count;
635
//| }
636
//| decimalAt = decimal - first;
637
//| if (decimalAt < 0) {
638
//| ++decimalAt;
639
//| }
640
//|
641
//| ensureCapacity(count, 0);
642
//| for (int i = 0; i < count; ++i) {
643
//| digits[i] = (byte) stringDigits.charAt(first++);
644
//| if (first == decimal) {
645
//| ++first;
646
//| }
647
//| }
648

649         // The maxDigits here could also be Integer.MAX_VALUE
650
set(stringDigits, stringDigits.length());
651
652         // Eliminate digits beyond maximum digits to be displayed.
653
// Round up if appropriate.
654
// {dlf} Some callers depend on passing '0' to round to mean 'don't round', but
655
// rather than pass that information explicitly, we rely on some magic with maximumDigits
656
// and decimalAt. Unfortunately, this is no good, because there are cases where maximumDigits
657
// is zero and we do want to round, e.g. BigDecimal values -1 < x < 1. So since round
658
// changed to perform rounding when the argument is 0, we now force the argument
659
// to -1 in the situations where it matters.
660
round(fixedPoint ? (maximumDigits + decimalAt) : maximumDigits == 0 ? -1 : maximumDigits);
661     }
662
663 //#ifndef FOUNDATION
664
//## /**
665
//## * Set the digit list to a representation of the given BigDecimal value.
666
//## * [bnf]
667
//## * @param source Value to be converted
668
//## * @param maximumDigits The most digits which should be converted.
669
//## * If maximumDigits is lower than the number of significant digits
670
//## * in source, the representation will be rounded. Ignored if <= 0.
671
//## * @param fixedPoint If true, then maximumDigits is the maximum
672
//## * fractional digits to be converted. If false, total digits.
673
//## */
674
//## public final void set(java.math.BigDecimal source,
675
//## int maximumDigits, boolean fixedPoint) {
676
//## setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint);
677
//## }
678
//#endif
679

680     /*
681      * Set the digit list to a representation of the given BigDecimal value.
682      * [bnf]
683      * @param source Value to be converted
684      * @param maximumDigits The most digits which should be converted.
685      * If maximumDigits is lower than the number of significant digits
686      * in source, the representation will be rounded. Ignored if <= 0.
687      * @param fixedPoint If true, then maximumDigits is the maximum
688      * fractional digits to be converted. If false, total digits.
689      */

690     public final void set(com.ibm.icu.math.BigDecimal source,
691                           int maximumDigits, boolean fixedPoint) {
692         setBigDecimalDigits(source.toString(), maximumDigits, fixedPoint);
693     }
694
695     /**
696      * Returns true if this DigitList represents Long.MIN_VALUE;
697      * false, otherwise. This is required so that getLong() works.
698      */

699     private boolean isLongMIN_VALUE()
700     {
701         if (decimalAt != count || count != MAX_LONG_DIGITS)
702             return false;
703
704             for (int i = 0; i < count; ++i)
705         {
706             if (digits[i] != LONG_MIN_REP[i]) return false;
707         }
708
709         return true;
710     }
711
712     private static byte[] LONG_MIN_REP;
713
714     static
715     {
716         // Store the representation of LONG_MIN without the leading '-'
717
String JavaDoc s = Long.toString(Long.MIN_VALUE);
718         LONG_MIN_REP = new byte[MAX_LONG_DIGITS];
719         for (int i=0; i < MAX_LONG_DIGITS; ++i)
720         {
721             LONG_MIN_REP[i] = (byte)s.charAt(i + 1);
722         }
723     }
724
725 // Unused -- Alan 2003-05
726
// /**
727
// * Return the floor of the log base 10 of a given double.
728
// * This method compensates for inaccuracies which arise naturally when
729
// * computing logs, and always give the correct value. The parameter
730
// * must be positive and finite.
731
// */
732
// private static final int log10(double d)
733
// {
734
// // The reason this routine is needed is that simply taking the
735
// // log and dividing by log10 yields a result which may be off
736
// // by 1 due to rounding errors. For example, the naive log10
737
// // of 1.0e300 taken this way is 299, rather than 300.
738
// double log10 = Math.log(d) / LOG10;
739
// int ilog10 = (int)Math.floor(log10);
740
// // Positive logs could be too small, e.g. 0.99 instead of 1.0
741
// if (log10 > 0 && d >= Math.pow(10, ilog10 + 1))
742
// {
743
// ++ilog10;
744
// }
745
// // Negative logs could be too big, e.g. -0.99 instead of -1.0
746
// else if (log10 < 0 && d < Math.pow(10, ilog10))
747
// {
748
// --ilog10;
749
// }
750
// return ilog10;
751
// }
752
//
753
// private static final double LOG10 = Math.log(10.0);
754

755     // (The following boilerplate methods are currently not called,
756
// and cannot be called by tests since this class is
757
// package-private. The methods may be useful in the future, so
758
// we do not delete them. 2003-06-11 ICU 2.6 Alan)
759
///CLOVER:OFF
760
/**
761      * equality test between two digit lists.
762      */

763     public boolean equals(Object JavaDoc obj) {
764         if (this == obj) // quick check
765
return true;
766         if (!(obj instanceof DigitList)) // (1) same object?
767
return false;
768         DigitList other = (DigitList) obj;
769         if (count != other.count ||
770         decimalAt != other.decimalAt)
771             return false;
772         for (int i = 0; i < count; i++)
773             if (digits[i] != other.digits[i])
774                 return false;
775         return true;
776     }
777
778     /**
779      * Generates the hash code for the digit list.
780      */

781     public int hashCode() {
782         int hashcode = decimalAt;
783
784         for (int i = 0; i < count; i++)
785             hashcode = hashcode * 37 + digits[i];
786
787         return hashcode;
788     }
789
790     public String JavaDoc toString()
791     {
792         if (isZero()) return "0";
793         StringBuffer JavaDoc buf = new StringBuffer JavaDoc("0.");
794         for (int i=0; i<count; ++i) buf.append((char)digits[i]);
795         buf.append("x10^");
796         buf.append(decimalAt);
797         return buf.toString();
798     }
799     ///CLOVER:ON
800
}
801
Popular Tags