Source Code Cross Referenced for DigitList.java in  » Internationalization-Localization » icu4j » com » ibm » icu » text » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Internationalization Localization » icu4j » com.ibm.icu.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        //##header
002:        /*
003:         *******************************************************************************
004:         * Copyright (C) 1996-2005, International Business Machines Corporation and    *
005:         * others. All Rights Reserved.                                                *
006:         *******************************************************************************
007:         */
008:        package com.ibm.icu.text;
009:
010:        import java.math.BigInteger;
011:
012:        /**
013:         * <code>DigitList</code> handles the transcoding between numeric values and
014:         * strings of characters.  It only represents non-negative numbers.  The
015:         * division of labor between <code>DigitList</code> and
016:         * <code>DecimalFormat</code> is that <code>DigitList</code> handles the radix
017:         * 10 representation issues and numeric conversion, including rounding;
018:         * <code>DecimalFormat</code> handles the locale-specific issues such as
019:         * positive and negative representation, digit grouping, decimal point,
020:         * currency, and so on.
021:         *
022:         * <p>A <code>DigitList</code> is a representation of a finite numeric value.
023:         * <code>DigitList</code> objects do not represent <code>NaN</code> or infinite
024:         * values.  A <code>DigitList</code> value can be converted to a
025:         * <code>BigDecimal</code> without loss of precision.  Conversion to other
026:         * numeric formats may involve loss of precision, depending on the specific
027:         * value.
028:         *
029:         * <p>The <code>DigitList</code> representation consists of a string of
030:         * characters, which are the digits radix 10, from '0' to '9'.  It also has a
031:         * base 10 exponent associated with it.  The value represented by a
032:         * <code>DigitList</code> object can be computed by mulitplying the fraction
033:         * <em>f</em>, where 0 <= <em>f</em> < 1, derived by placing all the digits of
034:         * the list to the right of the decimal point, by 10^exponent.
035:         *
036:         * @see java.util.Locale
037:         * @see java.text.Format
038:         * @see NumberFormat
039:         * @see DecimalFormat
040:         * @see java.text.ChoiceFormat
041:         * @see java.text.MessageFormat
042:         * @version      1.18 08/12/98
043:         * @author       Mark Davis, Alan Liu
044:         * */
045:        final class DigitList {
046:            /**
047:             * The maximum number of significant digits in an IEEE 754 double, that
048:             * is, in a Java double.  This must not be increased, or garbage digits
049:             * will be generated, and should not be decreased, or accuracy will be lost.
050:             */
051:            public static final int MAX_LONG_DIGITS = 19; // == Long.toString(Long.MAX_VALUE).length()
052:            public static final int DBL_DIG = 17;
053:
054:            /**
055:             * These data members are intentionally public and can be set directly.
056:             *
057:             * The value represented is given by placing the decimal point before
058:             * digits[decimalAt].  If decimalAt is < 0, then leading zeros between
059:             * the decimal point and the first nonzero digit are implied.  If decimalAt
060:             * is > count, then trailing zeros between the digits[count-1] and the
061:             * decimal point are implied.
062:             *
063:             * Equivalently, the represented value is given by f * 10^decimalAt.  Here
064:             * f is a value 0.1 <= f < 1 arrived at by placing the digits in Digits to
065:             * the right of the decimal.
066:             *
067:             * DigitList is normalized, so if it is non-zero, figits[0] is non-zero.  We
068:             * don't allow denormalized numbers because our exponent is effectively of
069:             * unlimited magnitude.  The count value contains the number of significant
070:             * digits present in digits[].
071:             *
072:             * Zero is represented by any DigitList with count == 0 or with each digits[i]
073:             * for all i <= count == '0'.
074:             */
075:            public int decimalAt = 0;
076:            public int count = 0;
077:            public byte[] digits = new byte[MAX_LONG_DIGITS];
078:
079:            private final void ensureCapacity(int digitCapacity,
080:                    int digitsToCopy) {
081:                if (digitCapacity > digits.length) {
082:                    byte[] newDigits = new byte[digitCapacity * 2];
083:                    System.arraycopy(digits, 0, newDigits, 0, digitsToCopy);
084:                    digits = newDigits;
085:                }
086:            }
087:
088:            /**
089:             * Return true if the represented number is zero.
090:             */
091:            boolean isZero() {
092:                for (int i = 0; i < count; ++i)
093:                    if (digits[i] != '0')
094:                        return false;
095:                return true;
096:            }
097:
098:            // Unused as of ICU 2.6 - alan
099:            //    /**
100:            //     * Clears out the digits.
101:            //     * Use before appending them.
102:            //     * Typically, you set a series of digits with append, then at the point
103:            //     * you hit the decimal point, you set myDigitList.decimalAt = myDigitList.count;
104:            //     * then go on appending digits.
105:            //     */
106:            //    public void clear () {
107:            //        decimalAt = 0;
108:            //        count = 0;
109:            //    }
110:
111:            /**
112:             * Appends digits to the list.
113:             */
114:            public void append(int digit) {
115:                ensureCapacity(count + 1, count);
116:                digits[count++] = (byte) digit;
117:            }
118:
119:            /**
120:             * Utility routine to get the value of the digit list
121:             * If (count == 0) this throws a NumberFormatException, which
122:             * mimics Long.parseLong().
123:             */
124:            public final double getDouble() {
125:                if (count == 0)
126:                    return 0.0;
127:                StringBuffer temp = new StringBuffer(count);
128:                temp.append('.');
129:                for (int i = 0; i < count; ++i)
130:                    temp.append((char) (digits[i]));
131:                temp.append('E');
132:                temp.append(Integer.toString(decimalAt));
133:                return Double.valueOf(temp.toString()).doubleValue();
134:                // long value = Long.parseLong(temp.toString());
135:                // return (value * Math.pow(10, decimalAt - count));
136:            }
137:
138:            /**
139:             * Utility routine to get the value of the digit list.
140:             * If (count == 0) this returns 0, unlike Long.parseLong().
141:             */
142:            public final long getLong() {
143:                // for now, simple implementation; later, do proper IEEE native stuff
144:
145:                if (count == 0)
146:                    return 0;
147:
148:                // We have to check for this, because this is the one NEGATIVE value
149:                // we represent.  If we tried to just pass the digits off to parseLong,
150:                // we'd get a parse failure.
151:                if (isLongMIN_VALUE())
152:                    return Long.MIN_VALUE;
153:
154:                StringBuffer temp = new StringBuffer(count);
155:                for (int i = 0; i < decimalAt; ++i) {
156:                    temp.append((i < count) ? (char) (digits[i]) : '0');
157:                }
158:                return Long.parseLong(temp.toString());
159:            }
160:
161:            /**
162:             * Return a <code>BigInteger</code> representing the value stored in this
163:             * <code>DigitList</code>.  This method assumes that this object contains
164:             * an integral value; if not, it will return an incorrect value.
165:             * [bnf]
166:             * @param isPositive determines the sign of the returned result
167:             * @return the value of this object as a <code>BigInteger</code>
168:             */
169:            public BigInteger getBigInteger(boolean isPositive) {
170:                if (isZero())
171:                    return BigInteger.valueOf(0);
172:                if (false) {
173:                    StringBuffer stringRep = new StringBuffer(count);
174:                    if (!isPositive) {
175:                        stringRep.append('-');
176:                    }
177:                    for (int i = 0; i < count; ++i) {
178:                        stringRep.append((char) digits[i]);
179:                    }
180:                    int d = decimalAt;
181:                    while (d-- > count) {
182:                        stringRep.append('0');
183:                    }
184:                    return new BigInteger(stringRep.toString());
185:                } else {
186:                    int len = decimalAt > count ? decimalAt : count;
187:                    if (!isPositive) {
188:                        len += 1;
189:                    }
190:                    char[] text = new char[len];
191:                    int n = 0;
192:                    if (!isPositive) {
193:                        text[0] = '-';
194:                        for (int i = 0; i < count; ++i) {
195:                            text[i + 1] = (char) digits[i];
196:                        }
197:                        n = count + 1;
198:                    } else {
199:                        for (int i = 0; i < count; ++i) {
200:                            text[i] = (char) digits[i];
201:                        }
202:                        n = count;
203:                    }
204:                    for (int i = n; i < text.length; ++i) {
205:                        text[i] = '0';
206:                    }
207:                    return new BigInteger(new String(text));
208:                }
209:            }
210:
211:            private String getStringRep(boolean isPositive) {
212:                if (isZero())
213:                    return "0";
214:                StringBuffer stringRep = new StringBuffer(count + 1);
215:                if (!isPositive) {
216:                    stringRep.append('-');
217:                }
218:                int d = decimalAt;
219:                if (d < 0) {
220:                    stringRep.append('.');
221:                    while (d < 0) {
222:                        stringRep.append('0');
223:                        ++d;
224:                    }
225:                    d = -1;
226:                }
227:                for (int i = 0; i < count; ++i) {
228:                    if (d == i) {
229:                        stringRep.append('.');
230:                    }
231:                    stringRep.append((char) digits[i]);
232:                }
233:                while (d-- > count) {
234:                    stringRep.append('0');
235:                }
236:                return stringRep.toString();
237:            }
238:
239:            //#ifndef FOUNDATION    
240:            /**
241:             * Return a <code>BigDecimal</code> representing the value stored in this
242:             * <code>DigitList</code>.
243:             * [bnf]
244:             * @param isPositive determines the sign of the returned result
245:             * @return the value of this object as a <code>BigDecimal</code>
246:             */
247:            public java.math.BigDecimal getBigDecimal(boolean isPositive) {
248:                if (isZero())
249:                    return java.math.BigDecimal.valueOf(0);
250:                return new java.math.BigDecimal(getStringRep(isPositive));
251:            }
252:
253:            //#endif
254:
255:            /**
256:             * Return an <code>ICU BigDecimal</code> representing the value stored in this
257:             * <code>DigitList</code>.
258:             * [bnf]
259:             * @param isPositive determines the sign of the returned result
260:             * @return the value of this object as a <code>BigDecimal</code>
261:             */
262:            public com.ibm.icu.math.BigDecimal getBigDecimalICU(
263:                    boolean isPositive) {
264:                if (isZero())
265:                    return com.ibm.icu.math.BigDecimal.valueOf(0);
266:                return new com.ibm.icu.math.BigDecimal(getStringRep(isPositive));
267:            }
268:
269:            /**
270:             * Return whether or not this objects represented value is an integer.
271:             * [bnf]
272:             * @return true if the represented value of this object is an integer
273:             */
274:            boolean isIntegral() {
275:                // Trim trailing zeros.  This does not change the represented value.
276:                while (count > 0 && digits[count - 1] == (byte) '0')
277:                    --count;
278:                return count == 0 || decimalAt >= count;
279:            }
280:
281:            // Unused as of ICU 2.6 - alan
282:            //    /**
283:            //     * Return true if the number represented by this object can fit into
284:            //     * a long.
285:            //     */
286:            //    boolean fitsIntoLong(boolean isPositive)
287:            //    {
288:            //        // Figure out if the result will fit in a long.  We have to
289:            //        // first look for nonzero digits after the decimal point;
290:            //        // then check the size.  If the digit count is 18 or less, then
291:            //        // the value can definitely be represented as a long.  If it is 19
292:            //        // then it may be too large.
293:            //
294:            //        // Trim trailing zeros.  This does not change the represented value.
295:            //        while (count > 0 && digits[count - 1] == (byte)'0') --count;
296:            //
297:            //        if (count == 0) {
298:            //            // Positive zero fits into a long, but negative zero can only
299:            //            // be represented as a double. - bug 4162852
300:            //            return isPositive;
301:            //        }
302:            //
303:            //        if (decimalAt < count || decimalAt > MAX_LONG_DIGITS) return false;
304:            //
305:            //        if (decimalAt < MAX_LONG_DIGITS) return true;
306:            //
307:            //        // At this point we have decimalAt == count, and count == MAX_LONG_DIGITS.
308:            //        // The number will overflow if it is larger than 9223372036854775807
309:            //        // or smaller than -9223372036854775808.
310:            //        for (int i=0; i<count; ++i)
311:            //        {
312:            //            byte dig = digits[i], max = LONG_MIN_REP[i];
313:            //            if (dig > max) return false;
314:            //            if (dig < max) return true;
315:            //        }
316:            //
317:            //        // At this point the first count digits match.  If decimalAt is less
318:            //        // than count, then the remaining digits are zero, and we return true.
319:            //        if (count < decimalAt) return true;
320:            //
321:            //        // Now we have a representation of Long.MIN_VALUE, without the leading
322:            //        // negative sign.  If this represents a positive value, then it does
323:            //        // not fit; otherwise it fits.
324:            //        return !isPositive;
325:            //    }
326:
327:            // Unused as of ICU 2.6 - alan
328:            //    /**
329:            //     * Set the digit list to a representation of the given double value.
330:            //     * This method supports fixed-point notation.
331:            //     * @param source Value to be converted; must not be Inf, -Inf, Nan,
332:            //     * or a value <= 0.
333:            //     * @param maximumFractionDigits The most fractional digits which should
334:            //     * be converted.
335:            //     */
336:            //    public final void set(double source, int maximumFractionDigits)
337:            //    {
338:            //        set(source, maximumFractionDigits, true);
339:            //    }
340:
341:            /**
342:             * Set the digit list to a representation of the given double value.
343:             * This method supports both fixed-point and exponential notation.
344:             * @param source Value to be converted; must not be Inf, -Inf, Nan,
345:             * or a value <= 0.
346:             * @param maximumDigits The most fractional or total digits which should
347:             * be converted.
348:             * @param fixedPoint If true, then maximumDigits is the maximum
349:             * fractional digits to be converted.  If false, total digits.
350:             */
351:            final void set(double source, int maximumDigits, boolean fixedPoint) {
352:                if (source == 0)
353:                    source = 0;
354:                // Generate a representation of the form DDDDD, DDDDD.DDDDD, or
355:                // DDDDDE+/-DDDDD.
356:                String rep = Double.toString(source);
357:
358:                set(rep, MAX_LONG_DIGITS);
359:
360:                if (fixedPoint) {
361:                    // The negative of the exponent represents the number of leading
362:                    // zeros between the decimal and the first non-zero digit, for
363:                    // a value < 0.1 (e.g., for 0.00123, -decimalAt == 2).  If this
364:                    // is more than the maximum fraction digits, then we have an underflow
365:                    // for the printed representation.
366:                    if (-decimalAt > maximumDigits) {
367:                        count = 0;
368:                        return;
369:                    } else if (-decimalAt == maximumDigits) {
370:                        if (shouldRoundUp(0)) {
371:                            count = 1;
372:                            ++decimalAt;
373:                            digits[0] = (byte) '1';
374:                        } else {
375:                            count = 0;
376:                        }
377:                        return;
378:                    }
379:                    // else fall through
380:                }
381:
382:                // Eliminate trailing zeros.
383:                while (count > 1 && digits[count - 1] == '0')
384:                    --count;
385:
386:                // Eliminate digits beyond maximum digits to be displayed.
387:                // Round up if appropriate.
388:                round(fixedPoint ? (maximumDigits + decimalAt)
389:                        : maximumDigits == 0 ? -1 : maximumDigits);
390:            }
391:
392:            /**
393:             * Given a string representation of the form DDDDD, DDDDD.DDDDD,
394:             * or DDDDDE+/-DDDDD, set this object's value to it.  Ignore
395:             * any leading '-'.
396:             */
397:            private void set(String rep, int maxCount) {
398:                decimalAt = -1;
399:                count = 0;
400:                int exponent = 0;
401:                // Number of zeros between decimal point and first non-zero digit after
402:                // decimal point, for numbers < 1.
403:                int leadingZerosAfterDecimal = 0;
404:                boolean nonZeroDigitSeen = false;
405:                // Skip over leading '-'
406:                int i = 0;
407:                if (rep.charAt(i) == '-') {
408:                    ++i;
409:                }
410:                for (; i < rep.length(); ++i) {
411:                    char c = rep.charAt(i);
412:                    if (c == '.') {
413:                        decimalAt = count;
414:                    } else if (c == 'e' || c == 'E') {
415:                        ++i;
416:                        // Integer.parseInt doesn't handle leading '+' signs
417:                        if (rep.charAt(i) == '+') {
418:                            ++i;
419:                        }
420:                        exponent = Integer.valueOf(rep.substring(i)).intValue();
421:                        break;
422:                    } else if (count < maxCount) {
423:                        if (!nonZeroDigitSeen) {
424:                            nonZeroDigitSeen = (c != '0');
425:                            if (!nonZeroDigitSeen && decimalAt != -1) {
426:                                ++leadingZerosAfterDecimal;
427:                            }
428:                        }
429:
430:                        if (nonZeroDigitSeen) {
431:                            ensureCapacity(count + 1, count);
432:                            digits[count++] = (byte) c;
433:                        }
434:                    }
435:                }
436:                if (decimalAt == -1) {
437:                    decimalAt = count;
438:                }
439:                decimalAt += exponent - leadingZerosAfterDecimal;
440:            }
441:
442:            /**
443:             * Return true if truncating the representation to the given number
444:             * of digits will result in an increment to the last digit.  This
445:             * method implements half-even rounding, the default rounding mode.
446:             * [bnf]
447:             * @param maximumDigits the number of digits to keep, from 0 to
448:             * <code>count-1</code>.  If 0, then all digits are rounded away, and
449:             * this method returns true if a one should be generated (e.g., formatting
450:             * 0.09 with "#.#").
451:             * @return true if digit <code>maximumDigits-1</code> should be
452:             * incremented
453:             */
454:            private boolean shouldRoundUp(int maximumDigits) {
455:                // variable not used boolean increment = false;
456:                // Implement IEEE half-even rounding
457:                /*Bug 4243108
458:                  format(0.0) gives "0.1" if preceded by parse("99.99") [Richard/GCL]
459:                 */
460:                if (maximumDigits < count) {
461:                    if (digits[maximumDigits] > '5') {
462:                        return true;
463:                    } else if (digits[maximumDigits] == '5') {
464:                        for (int i = maximumDigits + 1; i < count; ++i) {
465:                            if (digits[i] != '0') {
466:                                return true;
467:                            }
468:                        }
469:                        return maximumDigits > 0
470:                                && (digits[maximumDigits - 1] % 2 != 0);
471:                    }
472:                }
473:                return false;
474:            }
475:
476:            /**
477:             * Round the representation to the given number of digits.
478:             * @param maximumDigits The maximum number of digits to be shown.
479:             * Upon return, count will be less than or equal to maximumDigits.
480:             * This now performs rounding when maximumDigits is 0, formerly it did not.
481:             */
482:            public final void round(int maximumDigits) {
483:                // Eliminate digits beyond maximum digits to be displayed.
484:                // Round up if appropriate.
485:                // [bnf] rewritten to fix 4179818
486:                if (maximumDigits >= 0 && maximumDigits < count) {
487:                    if (shouldRoundUp(maximumDigits)) {
488:                        // Rounding up involves incrementing digits from LSD to MSD.
489:                        // In most cases this is simple, but in a worst case situation
490:                        // (9999..99) we have to adjust the decimalAt value.
491:                        for (;;) {
492:                            --maximumDigits;
493:                            if (maximumDigits < 0) {
494:                                // We have all 9's, so we increment to a single digit
495:                                // of one and adjust the exponent.
496:                                digits[0] = (byte) '1';
497:                                ++decimalAt;
498:                                maximumDigits = 0; // Adjust the count
499:                                break;
500:                            }
501:
502:                            ++digits[maximumDigits];
503:                            if (digits[maximumDigits] <= '9')
504:                                break;
505:                            // digits[maximumDigits] = '0'; // Unnecessary since we'll truncate this
506:                        }
507:                        ++maximumDigits; // Increment for use as count
508:                    }
509:                    count = maximumDigits;
510:                    /*Bug 4217661 DecimalFormat formats 1.001 to "1.00" instead of "1"
511:                      Eliminate trailing zeros. [Richard/GCL]
512:                     */
513:                    while (count > 1 && digits[count - 1] == '0') {
514:                        --count;
515:                    } //[Richard/GCL]
516:                }
517:            }
518:
519:            /**
520:             * Utility routine to set the value of the digit list from a long
521:             */
522:            public final void set(long source) {
523:                set(source, 0);
524:            }
525:
526:            /**
527:             * Set the digit list to a representation of the given long value.
528:             * @param source Value to be converted; must be >= 0 or ==
529:             * Long.MIN_VALUE.
530:             * @param maximumDigits The most digits which should be converted.
531:             * If maximumDigits is lower than the number of significant digits
532:             * in source, the representation will be rounded.  Ignored if <= 0.
533:             */
534:            public final void set(long source, int maximumDigits) {
535:                // This method does not expect a negative number. However,
536:                // "source" can be a Long.MIN_VALUE (-9223372036854775808),
537:                // if the number being formatted is a Long.MIN_VALUE.  In that
538:                // case, it will be formatted as -Long.MIN_VALUE, a number
539:                // which is outside the legal range of a long, but which can
540:                // be represented by DigitList.
541:                // [NEW] Faster implementation
542:                if (source <= 0) {
543:                    if (source == Long.MIN_VALUE) {
544:                        decimalAt = count = MAX_LONG_DIGITS;
545:                        System.arraycopy(LONG_MIN_REP, 0, digits, 0, count);
546:                    } else {
547:                        count = 0;
548:                        decimalAt = 0;
549:                    }
550:                } else {
551:                    int left = MAX_LONG_DIGITS;
552:                    int right;
553:                    while (source > 0) {
554:                        digits[--left] = (byte) (((long) '0') + (source % 10));
555:                        source /= 10;
556:                    }
557:                    decimalAt = MAX_LONG_DIGITS - left;
558:                    // Don't copy trailing zeros
559:                    // we are guaranteed that there is at least one non-zero digit,
560:                    // so we don't have to check lower bounds
561:                    for (right = MAX_LONG_DIGITS - 1; digits[right] == (byte) '0'; --right) {
562:                    }
563:                    count = right - left + 1;
564:                    System.arraycopy(digits, left, digits, 0, count);
565:                }
566:                if (maximumDigits > 0)
567:                    round(maximumDigits);
568:            }
569:
570:            /**
571:             * Set the digit list to a representation of the given BigInteger value.
572:             * [bnf]
573:             * @param source Value to be converted
574:             * @param maximumDigits The most digits which should be converted.
575:             * If maximumDigits is lower than the number of significant digits
576:             * in source, the representation will be rounded.  Ignored if <= 0.
577:             */
578:            public final void set(BigInteger source, int maximumDigits) {
579:                String stringDigits = source.toString();
580:
581:                count = decimalAt = stringDigits.length();
582:
583:                // Don't copy trailing zeros
584:                while (count > 1 && stringDigits.charAt(count - 1) == '0')
585:                    --count;
586:
587:                int offset = 0;
588:                if (stringDigits.charAt(0) == '-') {
589:                    ++offset;
590:                    --count;
591:                    --decimalAt;
592:                }
593:
594:                ensureCapacity(count, 0);
595:                for (int i = 0; i < count; ++i) {
596:                    digits[i] = (byte) stringDigits.charAt(i + offset);
597:                }
598:
599:                if (maximumDigits > 0)
600:                    round(maximumDigits);
601:            }
602:
603:            /**
604:             * Internal method that sets this digit list to represent the
605:             * given value.  The value is given as a String of the format
606:             * returned by BigDecimal.
607:             * @param stringDigits value to be represented with the following
608:             * syntax, expressed as a regular expression: -?\d*.?\d*
609:             * Must not be an empty string.
610:             * @param maximumDigits The most digits which should be converted.
611:             * If maximumDigits is lower than the number of significant digits
612:             * in source, the representation will be rounded.  Ignored if <= 0.
613:             * @param fixedPoint If true, then maximumDigits is the maximum
614:             * fractional digits to be converted.  If false, total digits.
615:             */
616:            private void setBigDecimalDigits(String stringDigits,
617:                    int maximumDigits, boolean fixedPoint) {
618:                //|        // Find the first non-zero digit, the decimal, and the last non-zero digit.
619:                //|        int first=-1, last=stringDigits.length()-1, decimal=-1;
620:                //|        for (int i=0; (first<0 || decimal<0) && i<=last; ++i) {
621:                //|            char c = stringDigits.charAt(i);
622:                //|            if (c == '.') {
623:                //|                decimal = i;
624:                //|            } else if (first < 0 && (c >= '1' && c <= '9')) {
625:                //|                first = i;
626:                //|            }
627:                //|        }
628:                //|
629:                //|        if (first < 0) {
630:                //|            clear();
631:                //|            return;
632:                //|        }
633:                //|
634:                //|        // At this point we know there is at least one non-zero digit, so the
635:                //|        // following loop is safe.
636:                //|        for (;;) {
637:                //|            char c = stringDigits.charAt(last);
638:                //|            if (c != '0' && c != '.') {
639:                //|                break;
640:                //|            }
641:                //|            --last;
642:                //|        }
643:                //|
644:                //|        if (decimal < 0) {
645:                //|            decimal = stringDigits.length();
646:                //|        }
647:                //|
648:                //|        count = last - first;
649:                //|        if (decimal < first || decimal > last) {
650:                //|            ++count;
651:                //|        }
652:                //|        decimalAt = decimal - first;
653:                //|        if (decimalAt < 0) {
654:                //|            ++decimalAt;
655:                //|        }
656:                //|
657:                //|        ensureCapacity(count, 0);
658:                //|        for (int i = 0; i < count; ++i) {
659:                //|            digits[i] = (byte) stringDigits.charAt(first++);
660:                //|            if (first == decimal) {
661:                //|                ++first;
662:                //|            }
663:                //|        }
664:
665:                // The maxDigits here could also be Integer.MAX_VALUE
666:                set(stringDigits, stringDigits.length());
667:
668:                // Eliminate digits beyond maximum digits to be displayed.
669:                // Round up if appropriate.
670:                // {dlf} Some callers depend on passing '0' to round to mean 'don't round', but
671:                // rather than pass that information explicitly, we rely on some magic with maximumDigits
672:                // and decimalAt.  Unfortunately, this is no good, because there are cases where maximumDigits
673:                // is zero and we do want to round, e.g. BigDecimal values -1 < x < 1.  So since round
674:                // changed to perform rounding when the argument is 0, we now force the argument
675:                // to -1 in the situations where it matters.
676:                round(fixedPoint ? (maximumDigits + decimalAt)
677:                        : maximumDigits == 0 ? -1 : maximumDigits);
678:            }
679:
680:            //#ifndef FOUNDATION
681:            /**
682:             * Set the digit list to a representation of the given BigDecimal value.
683:             * [bnf]
684:             * @param source Value to be converted
685:             * @param maximumDigits The most digits which should be converted.
686:             * If maximumDigits is lower than the number of significant digits
687:             * in source, the representation will be rounded.  Ignored if <= 0.
688:             * @param fixedPoint If true, then maximumDigits is the maximum
689:             * fractional digits to be converted.  If false, total digits.
690:             */
691:            public final void set(java.math.BigDecimal source,
692:                    int maximumDigits, boolean fixedPoint) {
693:                setBigDecimalDigits(source.toString(), maximumDigits,
694:                        fixedPoint);
695:            }
696:
697:            //#endif
698:
699:            /*
700:             * Set the digit list to a representation of the given BigDecimal value.
701:             * [bnf]
702:             * @param source Value to be converted
703:             * @param maximumDigits The most digits which should be converted.
704:             * If maximumDigits is lower than the number of significant digits
705:             * in source, the representation will be rounded.  Ignored if <= 0.
706:             * @param fixedPoint If true, then maximumDigits is the maximum
707:             * fractional digits to be converted.  If false, total digits.
708:             */
709:            public final void set(com.ibm.icu.math.BigDecimal source,
710:                    int maximumDigits, boolean fixedPoint) {
711:                setBigDecimalDigits(source.toString(), maximumDigits,
712:                        fixedPoint);
713:            }
714:
715:            /**
716:             * Returns true if this DigitList represents Long.MIN_VALUE;
717:             * false, otherwise.  This is required so that getLong() works.
718:             */
719:            private boolean isLongMIN_VALUE() {
720:                if (decimalAt != count || count != MAX_LONG_DIGITS)
721:                    return false;
722:
723:                for (int i = 0; i < count; ++i) {
724:                    if (digits[i] != LONG_MIN_REP[i])
725:                        return false;
726:                }
727:
728:                return true;
729:            }
730:
731:            private static byte[] LONG_MIN_REP;
732:
733:            static {
734:                // Store the representation of LONG_MIN without the leading '-'
735:                String s = Long.toString(Long.MIN_VALUE);
736:                LONG_MIN_REP = new byte[MAX_LONG_DIGITS];
737:                for (int i = 0; i < MAX_LONG_DIGITS; ++i) {
738:                    LONG_MIN_REP[i] = (byte) s.charAt(i + 1);
739:                }
740:            }
741:
742:            // Unused -- Alan 2003-05
743:            //    /**
744:            //     * Return the floor of the log base 10 of a given double.
745:            //     * This method compensates for inaccuracies which arise naturally when
746:            //     * computing logs, and always give the correct value.  The parameter
747:            //     * must be positive and finite.
748:            //     */
749:            //    private static final int log10(double d)
750:            //    {
751:            //        // The reason this routine is needed is that simply taking the
752:            //        // log and dividing by log10 yields a result which may be off
753:            //        // by 1 due to rounding errors.  For example, the naive log10
754:            //        // of 1.0e300 taken this way is 299, rather than 300.
755:            //        double log10 = Math.log(d) / LOG10;
756:            //        int ilog10 = (int)Math.floor(log10);
757:            //        // Positive logs could be too small, e.g. 0.99 instead of 1.0
758:            //        if (log10 > 0 && d >= Math.pow(10, ilog10 + 1))
759:            //        {
760:            //            ++ilog10;
761:            //        }
762:            //        // Negative logs could be too big, e.g. -0.99 instead of -1.0
763:            //        else if (log10 < 0 && d < Math.pow(10, ilog10))
764:            //        {
765:            //            --ilog10;
766:            //        }
767:            //        return ilog10;
768:            //    }
769:            //
770:            //    private static final double LOG10 = Math.log(10.0);
771:
772:            // (The following boilerplate methods are currently not called,
773:            // and cannot be called by tests since this class is
774:            // package-private.  The methods may be useful in the future, so
775:            // we do not delete them.  2003-06-11 ICU 2.6 Alan)
776:            ///CLOVER:OFF
777:            /**
778:             * equality test between two digit lists.
779:             */
780:            public boolean equals(Object obj) {
781:                if (this  == obj) // quick check
782:                    return true;
783:                if (!(obj instanceof  DigitList)) // (1) same object?
784:                    return false;
785:                DigitList other = (DigitList) obj;
786:                if (count != other.count || decimalAt != other.decimalAt)
787:                    return false;
788:                for (int i = 0; i < count; i++)
789:                    if (digits[i] != other.digits[i])
790:                        return false;
791:                return true;
792:            }
793:
794:            /**
795:             * Generates the hash code for the digit list.
796:             */
797:            public int hashCode() {
798:                int hashcode = decimalAt;
799:
800:                for (int i = 0; i < count; i++)
801:                    hashcode = hashcode * 37 + digits[i];
802:
803:                return hashcode;
804:            }
805:
806:            public String toString() {
807:                if (isZero())
808:                    return "0";
809:                StringBuffer buf = new StringBuffer("0.");
810:                for (int i = 0; i < count; ++i)
811:                    buf.append((char) digits[i]);
812:                buf.append("x10^");
813:                buf.append(decimalAt);
814:                return buf.toString();
815:            }
816:            ///CLOVER:ON
817:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.