blob: 734d065d11134b15cc8b53b5f1f57f8cbc303bf0 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26/*
27 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
29 *
30 * The original version of this source code and documentation is copyrighted
31 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
32 * materials are provided under terms of a License Agreement between Taligent
33 * and Sun. This technology is protected by multiple US and International
34 * patents. This notice and attribution to Taligent may not be removed.
35 * Taligent is a registered trademark of Taligent, Inc.
36 *
37 */
38
39package java.text;
40
41import java.io.InvalidObjectException;
42import java.io.IOException;
43import java.io.ObjectInputStream;
44import java.math.BigDecimal;
45import java.math.BigInteger;
46import java.math.RoundingMode;
47import java.util.ArrayList;
48import java.util.Currency;
49import java.util.Hashtable;
50import java.util.Locale;
51import java.util.ResourceBundle;
52import java.util.concurrent.atomic.AtomicInteger;
53import java.util.concurrent.atomic.AtomicLong;
54import sun.util.resources.LocaleData;
55
56/**
57 * <code>DecimalFormat</code> is a concrete subclass of
58 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
59 * features designed to make it possible to parse and format numbers in any
60 * locale, including support for Western, Arabic, and Indic digits. It also
61 * supports different kinds of numbers, including integers (123), fixed-point
62 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
63 * currency amounts ($123). All of these can be localized.
64 *
65 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
66 * default locale, call one of <code>NumberFormat</code>'s factory methods, such
67 * as <code>getInstance()</code>. In general, do not call the
68 * <code>DecimalFormat</code> constructors directly, since the
69 * <code>NumberFormat</code> factory methods may return subclasses other than
70 * <code>DecimalFormat</code>. If you need to customize the format object, do
71 * something like this:
72 *
73 * <blockquote><pre>
74 * NumberFormat f = NumberFormat.getInstance(loc);
75 * if (f instanceof DecimalFormat) {
76 * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
77 * }
78 * </pre></blockquote>
79 *
80 * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
81 * <em>symbols</em>. The pattern may be set directly using
82 * <code>applyPattern()</code>, or indirectly using the API methods. The
83 * symbols are stored in a <code>DecimalFormatSymbols</code> object. When using
84 * the <code>NumberFormat</code> factory methods, the pattern and symbols are
85 * read from localized <code>ResourceBundle</code>s.
86 *
87 * <h4>Patterns</h4>
88 *
89 * <code>DecimalFormat</code> patterns have the following syntax:
90 * <blockquote><pre>
91 * <i>Pattern:</i>
92 * <i>PositivePattern</i>
93 * <i>PositivePattern</i> ; <i>NegativePattern</i>
94 * <i>PositivePattern:</i>
95 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
96 * <i>NegativePattern:</i>
97 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
98 * <i>Prefix:</i>
99 * any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
100 * <i>Suffix:</i>
101 * any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
102 * <i>Number:</i>
103 * <i>Integer</i> <i>Exponent<sub>opt</sub></i>
104 * <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
105 * <i>Integer:</i>
106 * <i>MinimumInteger</i>
107 * #
108 * # <i>Integer</i>
109 * # , <i>Integer</i>
110 * <i>MinimumInteger:</i>
111 * 0
112 * 0 <i>MinimumInteger</i>
113 * 0 , <i>MinimumInteger</i>
114 * <i>Fraction:</i>
115 * <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
116 * <i>MinimumFraction:</i>
117 * 0 <i>MinimumFraction<sub>opt</sub></i>
118 * <i>OptionalFraction:</i>
119 * # <i>OptionalFraction<sub>opt</sub></i>
120 * <i>Exponent:</i>
121 * E <i>MinimumExponent</i>
122 * <i>MinimumExponent:</i>
123 * 0 <i>MinimumExponent<sub>opt</sub></i>
124 * </pre></blockquote>
125 *
126 * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
127 * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each
128 * subpattern has a prefix, numeric part, and suffix. The negative subpattern
129 * is optional; if absent, then the positive subpattern prefixed with the
130 * localized minus sign (<code>'-'</code> in most locales) is used as the
131 * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
132 * <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it
133 * serves only to specify the negative prefix and suffix; the number of digits,
134 * minimal digits, and other characteristics are all the same as the positive
135 * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
136 * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
137 *
138 * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
139 * thousands separators, decimal separators, etc. may be set to arbitrary
140 * values, and they will appear properly during formatting. However, care must
141 * be taken that the symbols and strings do not conflict, or parsing will be
142 * unreliable. For example, either the positive and negative prefixes or the
143 * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
144 * to distinguish positive from negative values. (If they are identical, then
145 * <code>DecimalFormat</code> will behave as if no negative subpattern was
146 * specified.) Another example is that the decimal separator and thousands
147 * separator should be distinct characters, or parsing will be impossible.
148 *
149 * <p>The grouping separator is commonly used for thousands, but in some
150 * countries it separates ten-thousands. The grouping size is a constant number
151 * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
152 * 1,0000,0000. If you supply a pattern with multiple grouping characters, the
153 * interval between the last one and the end of the integer is the one that is
154 * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
155 * <code>"##,####,####"</code>.
156 *
157 * <h4>Special Pattern Characters</h4>
158 *
159 * <p>Many characters in a pattern are taken literally; they are matched during
160 * parsing and output unchanged during formatting. Special characters, on the
161 * other hand, stand for other characters, strings, or classes of characters.
162 * They must be quoted, unless noted otherwise, if they are to appear in the
163 * prefix or suffix as literals.
164 *
165 * <p>The characters listed here are used in non-localized patterns. Localized
166 * patterns use the corresponding characters taken from this formatter's
167 * <code>DecimalFormatSymbols</code> object instead, and these characters lose
168 * their special status. Two exceptions are the currency sign and quote, which
169 * are not localized.
170 *
171 * <blockquote>
172 * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
173 * location, localized, and meaning.">
174 * <tr bgcolor="#ccccff">
175 * <th align=left>Symbol
176 * <th align=left>Location
177 * <th align=left>Localized?
178 * <th align=left>Meaning
179 * <tr valign=top>
180 * <td><code>0</code>
181 * <td>Number
182 * <td>Yes
183 * <td>Digit
184 * <tr valign=top bgcolor="#eeeeff">
185 * <td><code>#</code>
186 * <td>Number
187 * <td>Yes
188 * <td>Digit, zero shows as absent
189 * <tr valign=top>
190 * <td><code>.</code>
191 * <td>Number
192 * <td>Yes
193 * <td>Decimal separator or monetary decimal separator
194 * <tr valign=top bgcolor="#eeeeff">
195 * <td><code>-</code>
196 * <td>Number
197 * <td>Yes
198 * <td>Minus sign
199 * <tr valign=top>
200 * <td><code>,</code>
201 * <td>Number
202 * <td>Yes
203 * <td>Grouping separator
204 * <tr valign=top bgcolor="#eeeeff">
205 * <td><code>E</code>
206 * <td>Number
207 * <td>Yes
208 * <td>Separates mantissa and exponent in scientific notation.
209 * <em>Need not be quoted in prefix or suffix.</em>
210 * <tr valign=top>
211 * <td><code>;</code>
212 * <td>Subpattern boundary
213 * <td>Yes
214 * <td>Separates positive and negative subpatterns
215 * <tr valign=top bgcolor="#eeeeff">
216 * <td><code>%</code>
217 * <td>Prefix or suffix
218 * <td>Yes
219 * <td>Multiply by 100 and show as percentage
220 * <tr valign=top>
221 * <td><code>&#92;u2030</code>
222 * <td>Prefix or suffix
223 * <td>Yes
224 * <td>Multiply by 1000 and show as per mille value
225 * <tr valign=top bgcolor="#eeeeff">
226 * <td><code>&#164;</code> (<code>&#92;u00A4</code>)
227 * <td>Prefix or suffix
228 * <td>No
229 * <td>Currency sign, replaced by currency symbol. If
230 * doubled, replaced by international currency symbol.
231 * If present in a pattern, the monetary decimal separator
232 * is used instead of the decimal separator.
233 * <tr valign=top>
234 * <td><code>'</code>
235 * <td>Prefix or suffix
236 * <td>No
237 * <td>Used to quote special characters in a prefix or suffix,
238 * for example, <code>"'#'#"</code> formats 123 to
239 * <code>"#123"</code>. To create a single quote
240 * itself, use two in a row: <code>"# o''clock"</code>.
241 * </table>
242 * </blockquote>
243 *
244 * <h4>Scientific Notation</h4>
245 *
246 * <p>Numbers in scientific notation are expressed as the product of a mantissa
247 * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The
248 * mantissa is often in the range 1.0 <= x < 10.0, but it need not be.
249 * <code>DecimalFormat</code> can be instructed to format and parse scientific
250 * notation <em>only via a pattern</em>; there is currently no factory method
251 * that creates a scientific notation format. In a pattern, the exponent
252 * character immediately followed by one or more digit characters indicates
253 * scientific notation. Example: <code>"0.###E0"</code> formats the number
254 * 1234 as <code>"1.234E3"</code>.
255 *
256 * <ul>
257 * <li>The number of digit characters after the exponent character gives the
258 * minimum exponent digit count. There is no maximum. Negative exponents are
259 * formatted using the localized minus sign, <em>not</em> the prefix and suffix
260 * from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>.
261 *
262 * <li>The minimum and maximum number of integer digits are interpreted
263 * together:
264 *
265 * <ul>
266 * <li>If the maximum number of integer digits is greater than their minimum number
267 * and greater than 1, it forces the exponent to be a multiple of the maximum
268 * number of integer digits, and the minimum number of integer digits to be
269 * interpreted as 1. The most common use of this is to generate
270 * <em>engineering notation</em>, in which the exponent is a multiple of three,
271 * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
272 * formats to <code>"12.345E3"</code>, and 123456 formats to
273 * <code>"123.456E3"</code>.
274 *
275 * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
276 * exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields
277 * <code>"12.3E-4"</code>.
278 * </ul>
279 *
280 * <li>The number of significant digits in the mantissa is the sum of the
281 * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
282 * unaffected by the maximum integer digits. For example, 12345 formatted with
283 * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
284 * the significant digits count to zero. The number of significant digits
285 * does not affect parsing.
286 *
287 * <li>Exponential patterns may not contain grouping separators.
288 * </ul>
289 *
290 * <h4>Rounding</h4>
291 *
292 * <code>DecimalFormat</code> provides rounding modes defined in
293 * {@link java.math.RoundingMode} for formatting. By default, it uses
294 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
295 *
296 * <h4>Digits</h4>
297 *
298 * For formatting, <code>DecimalFormat</code> uses the ten consecutive
299 * characters starting with the localized zero digit defined in the
300 * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
301 * digits as well as all Unicode decimal digits, as defined by
302 * {@link Character#digit Character.digit}, are recognized.
303 *
304 * <h4>Special Values</h4>
305 *
306 * <p><code>NaN</code> is formatted as a string, which typically has a single character
307 * <code>&#92;uFFFD</code>. This string is determined by the
308 * <code>DecimalFormatSymbols</code> object. This is the only value for which
309 * the prefixes and suffixes are not used.
310 *
311 * <p>Infinity is formatted as a string, which typically has a single character
312 * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes
313 * applied. The infinity string is determined by the
314 * <code>DecimalFormatSymbols</code> object.
315 *
316 * <p>Negative zero (<code>"-0"</code>) parses to
317 * <ul>
318 * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
319 * true,
320 * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
321 * and <code>isParseIntegerOnly()</code> is true,
322 * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
323 * and <code>isParseIntegerOnly()</code> are false.
324 * </ul>
325 *
326 * <h4><a name="synchronization">Synchronization</a></h4>
327 *
328 * <p>
329 * Decimal formats are generally not synchronized.
330 * It is recommended to create separate format instances for each thread.
331 * If multiple threads access a format concurrently, it must be synchronized
332 * externally.
333 *
334 * <h4>Example</h4>
335 *
336 * <blockquote><pre>
337 * <strong>// Print out a number using the localized number, integer, currency,
338 * // and percent format for each locale</strong>
339 * Locale[] locales = NumberFormat.getAvailableLocales();
340 * double myNumber = -1234.56;
341 * NumberFormat form;
342 * for (int j=0; j<4; ++j) {
343 * System.out.println("FORMAT");
344 * for (int i = 0; i < locales.length; ++i) {
345 * if (locales[i].getCountry().length() == 0) {
346 * continue; // Skip language-only locales
347 * }
348 * System.out.print(locales[i].getDisplayName());
349 * switch (j) {
350 * case 0:
351 * form = NumberFormat.getInstance(locales[i]); break;
352 * case 1:
353 * form = NumberFormat.getIntegerInstance(locales[i]); break;
354 * case 2:
355 * form = NumberFormat.getCurrencyInstance(locales[i]); break;
356 * default:
357 * form = NumberFormat.getPercentInstance(locales[i]); break;
358 * }
359 * if (form instanceof DecimalFormat) {
360 * System.out.print(": " + ((DecimalFormat) form).toPattern());
361 * }
362 * System.out.print(" -> " + form.format(myNumber));
363 * try {
364 * System.out.println(" -> " + form.parse(form.format(myNumber)));
365 * } catch (ParseException e) {}
366 * }
367 * }
368 * </pre></blockquote>
369 *
370 * @see <a href="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
371 * @see NumberFormat
372 * @see DecimalFormatSymbols
373 * @see ParsePosition
374 * @author Mark Davis
375 * @author Alan Liu
376 */
377public class DecimalFormat extends NumberFormat {
378
379 /**
380 * Creates a DecimalFormat using the default pattern and symbols
381 * for the default locale. This is a convenient way to obtain a
382 * DecimalFormat when internationalization is not the main concern.
383 * <p>
384 * To obtain standard formats for a given locale, use the factory methods
385 * on NumberFormat such as getNumberInstance. These factories will
386 * return the most appropriate sub-class of NumberFormat for a given
387 * locale.
388 *
389 * @see java.text.NumberFormat#getInstance
390 * @see java.text.NumberFormat#getNumberInstance
391 * @see java.text.NumberFormat#getCurrencyInstance
392 * @see java.text.NumberFormat#getPercentInstance
393 */
394 public DecimalFormat() {
395 Locale def = Locale.getDefault();
396 // try to get the pattern from the cache
397 String pattern = (String) cachedLocaleData.get(def);
398 if (pattern == null) { /* cache miss */
399 // Get the pattern for the default locale.
400 ResourceBundle rb = LocaleData.getNumberFormatData(def);
401 String[] all = rb.getStringArray("NumberPatterns");
402 pattern = all[0];
403 /* update cache */
404 cachedLocaleData.put(def, pattern);
405 }
406
407 // Always applyPattern after the symbols are set
408 this.symbols = new DecimalFormatSymbols(def);
409 applyPattern(pattern, false);
410 }
411
412
413 /**
414 * Creates a DecimalFormat using the given pattern and the symbols
415 * for the default locale. This is a convenient way to obtain a
416 * DecimalFormat when internationalization is not the main concern.
417 * <p>
418 * To obtain standard formats for a given locale, use the factory methods
419 * on NumberFormat such as getNumberInstance. These factories will
420 * return the most appropriate sub-class of NumberFormat for a given
421 * locale.
422 *
423 * @param pattern A non-localized pattern string.
424 * @exception NullPointerException if <code>pattern</code> is null
425 * @exception IllegalArgumentException if the given pattern is invalid.
426 * @see java.text.NumberFormat#getInstance
427 * @see java.text.NumberFormat#getNumberInstance
428 * @see java.text.NumberFormat#getCurrencyInstance
429 * @see java.text.NumberFormat#getPercentInstance
430 */
431 public DecimalFormat(String pattern) {
432 // Always applyPattern after the symbols are set
433 this.symbols = new DecimalFormatSymbols(Locale.getDefault());
434 applyPattern(pattern, false);
435 }
436
437
438 /**
439 * Creates a DecimalFormat using the given pattern and symbols.
440 * Use this constructor when you need to completely customize the
441 * behavior of the format.
442 * <p>
443 * To obtain standard formats for a given
444 * locale, use the factory methods on NumberFormat such as
445 * getInstance or getCurrencyInstance. If you need only minor adjustments
446 * to a standard format, you can modify the format returned by
447 * a NumberFormat factory method.
448 *
449 * @param pattern a non-localized pattern string
450 * @param symbols the set of symbols to be used
451 * @exception NullPointerException if any of the given arguments is null
452 * @exception IllegalArgumentException if the given pattern is invalid
453 * @see java.text.NumberFormat#getInstance
454 * @see java.text.NumberFormat#getNumberInstance
455 * @see java.text.NumberFormat#getCurrencyInstance
456 * @see java.text.NumberFormat#getPercentInstance
457 * @see java.text.DecimalFormatSymbols
458 */
459 public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
460 // Always applyPattern after the symbols are set
461 this.symbols = (DecimalFormatSymbols)symbols.clone();
462 applyPattern(pattern, false);
463 }
464
465
466 // Overrides
467 /**
468 * Formats a number and appends the resulting text to the given string
469 * buffer.
470 * The number can be of any subclass of {@link java.lang.Number}.
471 * <p>
472 * This implementation uses the maximum precision permitted.
473 * @param number the number to format
474 * @param toAppendTo the <code>StringBuffer</code> to which the formatted
475 * text is to be appended
476 * @param pos On input: an alignment field, if desired.
477 * On output: the offsets of the alignment field.
478 * @return the value passed in as <code>toAppendTo</code>
479 * @exception IllegalArgumentException if <code>number</code> is
480 * null or not an instance of <code>Number</code>.
481 * @exception NullPointerException if <code>toAppendTo</code> or
482 * <code>pos</code> is null
483 * @exception ArithmeticException if rounding is needed with rounding
484 * mode being set to RoundingMode.UNNECESSARY
485 * @see java.text.FieldPosition
486 */
487 public final StringBuffer format(Object number,
488 StringBuffer toAppendTo,
489 FieldPosition pos) {
490 if (number instanceof Long || number instanceof Integer ||
491 number instanceof Short || number instanceof Byte ||
492 number instanceof AtomicInteger ||
493 number instanceof AtomicLong ||
494 (number instanceof BigInteger &&
495 ((BigInteger)number).bitLength () < 64)) {
496 return format(((Number)number).longValue(), toAppendTo, pos);
497 } else if (number instanceof BigDecimal) {
498 return format((BigDecimal)number, toAppendTo, pos);
499 } else if (number instanceof BigInteger) {
500 return format((BigInteger)number, toAppendTo, pos);
501 } else if (number instanceof Number) {
502 return format(((Number)number).doubleValue(), toAppendTo, pos);
503 } else {
504 throw new IllegalArgumentException("Cannot format given Object as a Number");
505 }
506 }
507
508 /**
509 * Formats a double to produce a string.
510 * @param number The double to format
511 * @param result where the text is to be appended
512 * @param fieldPosition On input: an alignment field, if desired.
513 * On output: the offsets of the alignment field.
514 * @exception ArithmeticException if rounding is needed with rounding
515 * mode being set to RoundingMode.UNNECESSARY
516 * @return The formatted number string
517 * @see java.text.FieldPosition
518 */
519 public StringBuffer format(double number, StringBuffer result,
520 FieldPosition fieldPosition) {
521 fieldPosition.setBeginIndex(0);
522 fieldPosition.setEndIndex(0);
523
524 return format(number, result, fieldPosition.getFieldDelegate());
525 }
526
527 /**
528 * Formats a double to produce a string.
529 * @param number The double to format
530 * @param result where the text is to be appended
531 * @param delegate notified of locations of sub fields
532 * @exception ArithmeticException if rounding is needed with rounding
533 * mode being set to RoundingMode.UNNECESSARY
534 * @return The formatted number string
535 */
536 private StringBuffer format(double number, StringBuffer result,
537 FieldDelegate delegate) {
538 if (Double.isNaN(number) ||
539 (Double.isInfinite(number) && multiplier == 0)) {
540 int iFieldStart = result.length();
541 result.append(symbols.getNaN());
542 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
543 iFieldStart, result.length(), result);
544 return result;
545 }
546
547 /* Detecting whether a double is negative is easy with the exception of
548 * the value -0.0. This is a double which has a zero mantissa (and
549 * exponent), but a negative sign bit. It is semantically distinct from
550 * a zero with a positive sign bit, and this distinction is important
551 * to certain kinds of computations. However, it's a little tricky to
552 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may
553 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==
554 * -Infinity. Proper detection of -0.0 is needed to deal with the
555 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
556 */
557 boolean isNegative = ((number < 0.0) || (number == 0.0 && 1/number < 0.0)) ^ (multiplier < 0);
558
559 if (multiplier != 1) {
560 number *= multiplier;
561 }
562
563 if (Double.isInfinite(number)) {
564 if (isNegative) {
565 append(result, negativePrefix, delegate,
566 getNegativePrefixFieldPositions(), Field.SIGN);
567 } else {
568 append(result, positivePrefix, delegate,
569 getPositivePrefixFieldPositions(), Field.SIGN);
570 }
571
572 int iFieldStart = result.length();
573 result.append(symbols.getInfinity());
574 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
575 iFieldStart, result.length(), result);
576
577 if (isNegative) {
578 append(result, negativeSuffix, delegate,
579 getNegativeSuffixFieldPositions(), Field.SIGN);
580 } else {
581 append(result, positiveSuffix, delegate,
582 getPositiveSuffixFieldPositions(), Field.SIGN);
583 }
584
585 return result;
586 }
587
588 if (isNegative) {
589 number = -number;
590 }
591
592 // at this point we are guaranteed a nonnegative finite number.
593 assert(number >= 0 && !Double.isInfinite(number));
594
595 synchronized(digitList) {
596 int maxIntDigits = super.getMaximumIntegerDigits();
597 int minIntDigits = super.getMinimumIntegerDigits();
598 int maxFraDigits = super.getMaximumFractionDigits();
599 int minFraDigits = super.getMinimumFractionDigits();
600
601 digitList.set(isNegative, number, useExponentialNotation ?
602 maxIntDigits + maxFraDigits : maxFraDigits,
603 !useExponentialNotation);
604 return subformat(result, delegate, isNegative, false,
605 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
606 }
607 }
608
609 /**
610 * Format a long to produce a string.
611 * @param number The long to format
612 * @param result where the text is to be appended
613 * @param fieldPosition On input: an alignment field, if desired.
614 * On output: the offsets of the alignment field.
615 * @exception ArithmeticException if rounding is needed with rounding
616 * mode being set to RoundingMode.UNNECESSARY
617 * @return The formatted number string
618 * @see java.text.FieldPosition
619 */
620 public StringBuffer format(long number, StringBuffer result,
621 FieldPosition fieldPosition) {
622 fieldPosition.setBeginIndex(0);
623 fieldPosition.setEndIndex(0);
624
625 return format(number, result, fieldPosition.getFieldDelegate());
626 }
627
628 /**
629 * Format a long to produce a string.
630 * @param number The long to format
631 * @param result where the text is to be appended
632 * @param delegate notified of locations of sub fields
633 * @return The formatted number string
634 * @exception ArithmeticException if rounding is needed with rounding
635 * mode being set to RoundingMode.UNNECESSARY
636 * @see java.text.FieldPosition
637 */
638 private StringBuffer format(long number, StringBuffer result,
639 FieldDelegate delegate) {
640 boolean isNegative = (number < 0);
641 if (isNegative) {
642 number = -number;
643 }
644
645 // In general, long values always represent real finite numbers, so
646 // we don't have to check for +/- Infinity or NaN. However, there
647 // is one case we have to be careful of: The multiplier can push
648 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We
649 // check for this before multiplying, and if it happens we use
650 // BigInteger instead.
651 boolean useBigInteger = false;
652 if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
653 if (multiplier != 0) {
654 useBigInteger = true;
655 }
656 } else if (multiplier != 1 && multiplier != 0) {
657 long cutoff = Long.MAX_VALUE / multiplier;
658 if (cutoff < 0) {
659 cutoff = -cutoff;
660 }
661 useBigInteger = (number > cutoff);
662 }
663
664 if (useBigInteger) {
665 if (isNegative) {
666 number = -number;
667 }
668 BigInteger bigIntegerValue = BigInteger.valueOf(number);
669 return format(bigIntegerValue, result, delegate, true);
670 }
671
672 number *= multiplier;
673 if (number == 0) {
674 isNegative = false;
675 } else {
676 if (multiplier < 0) {
677 number = -number;
678 isNegative = !isNegative;
679 }
680 }
681
682 synchronized(digitList) {
683 int maxIntDigits = super.getMaximumIntegerDigits();
684 int minIntDigits = super.getMinimumIntegerDigits();
685 int maxFraDigits = super.getMaximumFractionDigits();
686 int minFraDigits = super.getMinimumFractionDigits();
687
688 digitList.set(isNegative, number,
689 useExponentialNotation ? maxIntDigits + maxFraDigits : 0);
690
691 return subformat(result, delegate, isNegative, true,
692 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
693 }
694 }
695
696 /**
697 * Formats a BigDecimal to produce a string.
698 * @param number The BigDecimal to format
699 * @param result where the text is to be appended
700 * @param fieldPosition On input: an alignment field, if desired.
701 * On output: the offsets of the alignment field.
702 * @return The formatted number string
703 * @exception ArithmeticException if rounding is needed with rounding
704 * mode being set to RoundingMode.UNNECESSARY
705 * @see java.text.FieldPosition
706 */
707 private StringBuffer format(BigDecimal number, StringBuffer result,
708 FieldPosition fieldPosition) {
709 fieldPosition.setBeginIndex(0);
710 fieldPosition.setEndIndex(0);
711 return format(number, result, fieldPosition.getFieldDelegate());
712 }
713
714 /**
715 * Formats a BigDecimal to produce a string.
716 * @param number The BigDecimal to format
717 * @param result where the text is to be appended
718 * @param delegate notified of locations of sub fields
719 * @exception ArithmeticException if rounding is needed with rounding
720 * mode being set to RoundingMode.UNNECESSARY
721 * @return The formatted number string
722 */
723 private StringBuffer format(BigDecimal number, StringBuffer result,
724 FieldDelegate delegate) {
725 if (multiplier != 1) {
726 number = number.multiply(getBigDecimalMultiplier());
727 }
728 boolean isNegative = number.signum() == -1;
729 if (isNegative) {
730 number = number.negate();
731 }
732
733 synchronized(digitList) {
734 int maxIntDigits = getMaximumIntegerDigits();
735 int minIntDigits = getMinimumIntegerDigits();
736 int maxFraDigits = getMaximumFractionDigits();
737 int minFraDigits = getMinimumFractionDigits();
738 int maximumDigits = maxIntDigits + maxFraDigits;
739
740 digitList.set(isNegative, number, useExponentialNotation ?
741 ((maximumDigits < 0) ? Integer.MAX_VALUE : maximumDigits) :
742 maxFraDigits, !useExponentialNotation);
743
744 return subformat(result, delegate, isNegative, false,
745 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
746 }
747 }
748
749 /**
750 * Format a BigInteger to produce a string.
751 * @param number The BigInteger to format
752 * @param result where the text is to be appended
753 * @param fieldPosition On input: an alignment field, if desired.
754 * On output: the offsets of the alignment field.
755 * @return The formatted number string
756 * @exception ArithmeticException if rounding is needed with rounding
757 * mode being set to RoundingMode.UNNECESSARY
758 * @see java.text.FieldPosition
759 */
760 private StringBuffer format(BigInteger number, StringBuffer result,
761 FieldPosition fieldPosition) {
762 fieldPosition.setBeginIndex(0);
763 fieldPosition.setEndIndex(0);
764
765 return format(number, result, fieldPosition.getFieldDelegate(), false);
766 }
767
768 /**
769 * Format a BigInteger to produce a string.
770 * @param number The BigInteger to format
771 * @param result where the text is to be appended
772 * @param delegate notified of locations of sub fields
773 * @return The formatted number string
774 * @exception ArithmeticException if rounding is needed with rounding
775 * mode being set to RoundingMode.UNNECESSARY
776 * @see java.text.FieldPosition
777 */
778 private StringBuffer format(BigInteger number, StringBuffer result,
779 FieldDelegate delegate, boolean formatLong) {
780 if (multiplier != 1) {
781 number = number.multiply(getBigIntegerMultiplier());
782 }
783 boolean isNegative = number.signum() == -1;
784 if (isNegative) {
785 number = number.negate();
786 }
787
788 synchronized(digitList) {
789 int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
790 if (formatLong) {
791 maxIntDigits = super.getMaximumIntegerDigits();
792 minIntDigits = super.getMinimumIntegerDigits();
793 maxFraDigits = super.getMaximumFractionDigits();
794 minFraDigits = super.getMinimumFractionDigits();
795 maximumDigits = maxIntDigits + maxFraDigits;
796 } else {
797 maxIntDigits = getMaximumIntegerDigits();
798 minIntDigits = getMinimumIntegerDigits();
799 maxFraDigits = getMaximumFractionDigits();
800 minFraDigits = getMinimumFractionDigits();
801 maximumDigits = maxIntDigits + maxFraDigits;
802 if (maximumDigits < 0) {
803 maximumDigits = Integer.MAX_VALUE;
804 }
805 }
806
807 digitList.set(isNegative, number,
808 useExponentialNotation ? maximumDigits : 0);
809
810 return subformat(result, delegate, isNegative, true,
811 maxIntDigits, minIntDigits, maxFraDigits, minFraDigits);
812 }
813 }
814
815 /**
816 * Formats an Object producing an <code>AttributedCharacterIterator</code>.
817 * You can use the returned <code>AttributedCharacterIterator</code>
818 * to build the resulting String, as well as to determine information
819 * about the resulting String.
820 * <p>
821 * Each attribute key of the AttributedCharacterIterator will be of type
822 * <code>NumberFormat.Field</code>, with the attribute value being the
823 * same as the attribute key.
824 *
825 * @exception NullPointerException if obj is null.
826 * @exception IllegalArgumentException when the Format cannot format the
827 * given object.
828 * @exception ArithmeticException if rounding is needed with rounding
829 * mode being set to RoundingMode.UNNECESSARY
830 * @param obj The object to format
831 * @return AttributedCharacterIterator describing the formatted value.
832 * @since 1.4
833 */
834 public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
835 CharacterIteratorFieldDelegate delegate =
836 new CharacterIteratorFieldDelegate();
837 StringBuffer sb = new StringBuffer();
838
839 if (obj instanceof Double || obj instanceof Float) {
840 format(((Number)obj).doubleValue(), sb, delegate);
841 } else if (obj instanceof Long || obj instanceof Integer ||
842 obj instanceof Short || obj instanceof Byte ||
843 obj instanceof AtomicInteger || obj instanceof AtomicLong) {
844 format(((Number)obj).longValue(), sb, delegate);
845 } else if (obj instanceof BigDecimal) {
846 format((BigDecimal)obj, sb, delegate);
847 } else if (obj instanceof BigInteger) {
848 format((BigInteger)obj, sb, delegate, false);
849 } else if (obj == null) {
850 throw new NullPointerException(
851 "formatToCharacterIterator must be passed non-null object");
852 } else {
853 throw new IllegalArgumentException(
854 "Cannot format given Object as a Number");
855 }
856 return delegate.getIterator(sb.toString());
857 }
858
859 /**
860 * Complete the formatting of a finite number. On entry, the digitList must
861 * be filled in with the correct digits.
862 */
863 private StringBuffer subformat(StringBuffer result, FieldDelegate delegate,
864 boolean isNegative, boolean isInteger,
865 int maxIntDigits, int minIntDigits,
866 int maxFraDigits, int minFraDigits) {
867 // NOTE: This isn't required anymore because DigitList takes care of this.
868 //
869 // // The negative of the exponent represents the number of leading
870 // // zeros between the decimal and the first non-zero digit, for
871 // // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this
872 // // is more than the maximum fraction digits, then we have an underflow
873 // // for the printed representation. We recognize this here and set
874 // // the DigitList representation to zero in this situation.
875 //
876 // if (-digitList.decimalAt >= getMaximumFractionDigits())
877 // {
878 // digitList.count = 0;
879 // }
880
881 char zero = symbols.getZeroDigit();
882 int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
883 char grouping = symbols.getGroupingSeparator();
884 char decimal = isCurrencyFormat ?
885 symbols.getMonetaryDecimalSeparator() :
886 symbols.getDecimalSeparator();
887
888 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
889 * format as zero. This allows sensible computations and preserves
890 * relations such as signum(1/x) = signum(x), where x is +Infinity or
891 * -Infinity. Prior to this fix, we always formatted zero values as if
892 * they were positive. Liu 7/6/98.
893 */
894 if (digitList.isZero()) {
895 digitList.decimalAt = 0; // Normalize
896 }
897
898 if (isNegative) {
899 append(result, negativePrefix, delegate,
900 getNegativePrefixFieldPositions(), Field.SIGN);
901 } else {
902 append(result, positivePrefix, delegate,
903 getPositivePrefixFieldPositions(), Field.SIGN);
904 }
905
906 if (useExponentialNotation) {
907 int iFieldStart = result.length();
908 int iFieldEnd = -1;
909 int fFieldStart = -1;
910
911 // Minimum integer digits are handled in exponential format by
912 // adjusting the exponent. For example, 0.01234 with 3 minimum
913 // integer digits is "123.4E-4".
914
915 // Maximum integer digits are interpreted as indicating the
916 // repeating range. This is useful for engineering notation, in
917 // which the exponent is restricted to a multiple of 3. For
918 // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
919 // If maximum integer digits are > 1 and are larger than
920 // minimum integer digits, then minimum integer digits are
921 // ignored.
922 int exponent = digitList.decimalAt;
923 int repeat = maxIntDigits;
924 int minimumIntegerDigits = minIntDigits;
925 if (repeat > 1 && repeat > minIntDigits) {
926 // A repeating range is defined; adjust to it as follows.
927 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
928 // -3,-4,-5=>-6, etc. This takes into account that the
929 // exponent we have here is off by one from what we expect;
930 // it is for the format 0.MMMMMx10^n.
931 if (exponent >= 1) {
932 exponent = ((exponent - 1) / repeat) * repeat;
933 } else {
934 // integer division rounds towards 0
935 exponent = ((exponent - repeat) / repeat) * repeat;
936 }
937 minimumIntegerDigits = 1;
938 } else {
939 // No repeating range is defined; use minimum integer digits.
940 exponent -= minimumIntegerDigits;
941 }
942
943 // We now output a minimum number of digits, and more if there
944 // are more digits, up to the maximum number of digits. We
945 // place the decimal point after the "integer" digits, which
946 // are the first (decimalAt - exponent) digits.
947 int minimumDigits = minIntDigits + minFraDigits;
948 if (minimumDigits < 0) { // overflow?
949 minimumDigits = Integer.MAX_VALUE;
950 }
951
952 // The number of integer digits is handled specially if the number
953 // is zero, since then there may be no digits.
954 int integerDigits = digitList.isZero() ? minimumIntegerDigits :
955 digitList.decimalAt - exponent;
956 if (minimumDigits < integerDigits) {
957 minimumDigits = integerDigits;
958 }
959 int totalDigits = digitList.count;
960 if (minimumDigits > totalDigits) {
961 totalDigits = minimumDigits;
962 }
963 boolean addedDecimalSeparator = false;
964
965 for (int i=0; i<totalDigits; ++i) {
966 if (i == integerDigits) {
967 // Record field information for caller.
968 iFieldEnd = result.length();
969
970 result.append(decimal);
971 addedDecimalSeparator = true;
972
973 // Record field information for caller.
974 fFieldStart = result.length();
975 }
976 result.append((i < digitList.count) ?
977 (char)(digitList.digits[i] + zeroDelta) :
978 zero);
979 }
980
981 if (decimalSeparatorAlwaysShown && totalDigits == integerDigits) {
982 // Record field information for caller.
983 iFieldEnd = result.length();
984
985 result.append(decimal);
986 addedDecimalSeparator = true;
987
988 // Record field information for caller.
989 fFieldStart = result.length();
990 }
991
992 // Record field information
993 if (iFieldEnd == -1) {
994 iFieldEnd = result.length();
995 }
996 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
997 iFieldStart, iFieldEnd, result);
998 if (addedDecimalSeparator) {
999 delegate.formatted(Field.DECIMAL_SEPARATOR,
1000 Field.DECIMAL_SEPARATOR,
1001 iFieldEnd, fFieldStart, result);
1002 }
1003 if (fFieldStart == -1) {
1004 fFieldStart = result.length();
1005 }
1006 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1007 fFieldStart, result.length(), result);
1008
1009 // The exponent is output using the pattern-specified minimum
1010 // exponent digits. There is no maximum limit to the exponent
1011 // digits, since truncating the exponent would result in an
1012 // unacceptable inaccuracy.
1013 int fieldStart = result.length();
1014
1015 result.append(symbols.getExponentSeparator());
1016
1017 delegate.formatted(Field.EXPONENT_SYMBOL, Field.EXPONENT_SYMBOL,
1018 fieldStart, result.length(), result);
1019
1020 // For zero values, we force the exponent to zero. We
1021 // must do this here, and not earlier, because the value
1022 // is used to determine integer digit count above.
1023 if (digitList.isZero()) {
1024 exponent = 0;
1025 }
1026
1027 boolean negativeExponent = exponent < 0;
1028 if (negativeExponent) {
1029 exponent = -exponent;
1030 fieldStart = result.length();
1031 result.append(symbols.getMinusSign());
1032 delegate.formatted(Field.EXPONENT_SIGN, Field.EXPONENT_SIGN,
1033 fieldStart, result.length(), result);
1034 }
1035 digitList.set(negativeExponent, exponent);
1036
1037 int eFieldStart = result.length();
1038
1039 for (int i=digitList.decimalAt; i<minExponentDigits; ++i) {
1040 result.append(zero);
1041 }
1042 for (int i=0; i<digitList.decimalAt; ++i) {
1043 result.append((i < digitList.count) ?
1044 (char)(digitList.digits[i] + zeroDelta) : zero);
1045 }
1046 delegate.formatted(Field.EXPONENT, Field.EXPONENT, eFieldStart,
1047 result.length(), result);
1048 } else {
1049 int iFieldStart = result.length();
1050
1051 // Output the integer portion. Here 'count' is the total
1052 // number of integer digits we will display, including both
1053 // leading zeros required to satisfy getMinimumIntegerDigits,
1054 // and actual digits present in the number.
1055 int count = minIntDigits;
1056 int digitIndex = 0; // Index into digitList.fDigits[]
1057 if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
1058 count = digitList.decimalAt;
1059 }
1060
1061 // Handle the case where getMaximumIntegerDigits() is smaller
1062 // than the real number of integer digits. If this is so, we
1063 // output the least significant max integer digits. For example,
1064 // the value 1997 printed with 2 max integer digits is just "97".
1065 if (count > maxIntDigits) {
1066 count = maxIntDigits;
1067 digitIndex = digitList.decimalAt - count;
1068 }
1069
1070 int sizeBeforeIntegerPart = result.length();
1071 for (int i=count-1; i>=0; --i) {
1072 if (i < digitList.decimalAt && digitIndex < digitList.count) {
1073 // Output a real digit
1074 result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1075 } else {
1076 // Output a leading zero
1077 result.append(zero);
1078 }
1079
1080 // Output grouping separator if necessary. Don't output a
1081 // grouping separator if i==0 though; that's at the end of
1082 // the integer part.
1083 if (isGroupingUsed() && i>0 && (groupingSize != 0) &&
1084 (i % groupingSize == 0)) {
1085 int gStart = result.length();
1086 result.append(grouping);
1087 delegate.formatted(Field.GROUPING_SEPARATOR,
1088 Field.GROUPING_SEPARATOR, gStart,
1089 result.length(), result);
1090 }
1091 }
1092
1093 // Determine whether or not there are any printable fractional
1094 // digits. If we've used up the digits we know there aren't.
1095 boolean fractionPresent = (minFraDigits > 0) ||
1096 (!isInteger && digitIndex < digitList.count);
1097
1098 // If there is no fraction present, and we haven't printed any
1099 // integer digits, then print a zero. Otherwise we won't print
1100 // _any_ digits, and we won't be able to parse this string.
1101 if (!fractionPresent && result.length() == sizeBeforeIntegerPart) {
1102 result.append(zero);
1103 }
1104
1105 delegate.formatted(INTEGER_FIELD, Field.INTEGER, Field.INTEGER,
1106 iFieldStart, result.length(), result);
1107
1108 // Output the decimal separator if we always do so.
1109 int sStart = result.length();
1110 if (decimalSeparatorAlwaysShown || fractionPresent) {
1111 result.append(decimal);
1112 }
1113
1114 if (sStart != result.length()) {
1115 delegate.formatted(Field.DECIMAL_SEPARATOR,
1116 Field.DECIMAL_SEPARATOR,
1117 sStart, result.length(), result);
1118 }
1119 int fFieldStart = result.length();
1120
1121 for (int i=0; i < maxFraDigits; ++i) {
1122 // Here is where we escape from the loop. We escape if we've
1123 // output the maximum fraction digits (specified in the for
1124 // expression above).
1125 // We also stop when we've output the minimum digits and either:
1126 // we have an integer, so there is no fractional stuff to
1127 // display, or we're out of significant digits.
1128 if (i >= minFraDigits &&
1129 (isInteger || digitIndex >= digitList.count)) {
1130 break;
1131 }
1132
1133 // Output leading fractional zeros. These are zeros that come
1134 // after the decimal but before any significant digits. These
1135 // are only output if abs(number being formatted) < 1.0.
1136 if (-1-i > (digitList.decimalAt-1)) {
1137 result.append(zero);
1138 continue;
1139 }
1140
1141 // Output a digit, if we have any precision left, or a
1142 // zero if we don't. We don't want to output noise digits.
1143 if (!isInteger && digitIndex < digitList.count) {
1144 result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
1145 } else {
1146 result.append(zero);
1147 }
1148 }
1149
1150 // Record field information for caller.
1151 delegate.formatted(FRACTION_FIELD, Field.FRACTION, Field.FRACTION,
1152 fFieldStart, result.length(), result);
1153 }
1154
1155 if (isNegative) {
1156 append(result, negativeSuffix, delegate,
1157 getNegativeSuffixFieldPositions(), Field.SIGN);
1158 }
1159 else {
1160 append(result, positiveSuffix, delegate,
1161 getPositiveSuffixFieldPositions(), Field.SIGN);
1162 }
1163
1164 return result;
1165 }
1166
1167 /**
1168 * Appends the String <code>string</code> to <code>result</code>.
1169 * <code>delegate</code> is notified of all the
1170 * <code>FieldPosition</code>s in <code>positions</code>.
1171 * <p>
1172 * If one of the <code>FieldPosition</code>s in <code>positions</code>
1173 * identifies a <code>SIGN</code> attribute, it is mapped to
1174 * <code>signAttribute</code>. This is used
1175 * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
1176 * attribute as necessary.
1177 * <p>
1178 * This is used by <code>subformat</code> to add the prefix/suffix.
1179 */
1180 private void append(StringBuffer result, String string,
1181 FieldDelegate delegate,
1182 FieldPosition[] positions,
1183 Format.Field signAttribute) {
1184 int start = result.length();
1185
1186 if (string.length() > 0) {
1187 result.append(string);
1188 for (int counter = 0, max = positions.length; counter < max;
1189 counter++) {
1190 FieldPosition fp = positions[counter];
1191 Format.Field attribute = fp.getFieldAttribute();
1192
1193 if (attribute == Field.SIGN) {
1194 attribute = signAttribute;
1195 }
1196 delegate.formatted(attribute, attribute,
1197 start + fp.getBeginIndex(),
1198 start + fp.getEndIndex(), result);
1199 }
1200 }
1201 }
1202
1203 /**
1204 * Parses text from a string to produce a <code>Number</code>.
1205 * <p>
1206 * The method attempts to parse text starting at the index given by
1207 * <code>pos</code>.
1208 * If parsing succeeds, then the index of <code>pos</code> is updated
1209 * to the index after the last character used (parsing does not necessarily
1210 * use all characters up to the end of the string), and the parsed
1211 * number is returned. The updated <code>pos</code> can be used to
1212 * indicate the starting point for the next call to this method.
1213 * If an error occurs, then the index of <code>pos</code> is not
1214 * changed, the error index of <code>pos</code> is set to the index of
1215 * the character where the error occurred, and null is returned.
1216 * <p>
1217 * The subclass returned depends on the value of {@link #isParseBigDecimal}
1218 * as well as on the string being parsed.
1219 * <ul>
1220 * <li>If <code>isParseBigDecimal()</code> is false (the default),
1221 * most integer values are returned as <code>Long</code>
1222 * objects, no matter how they are written: <code>"17"</code> and
1223 * <code>"17.000"</code> both parse to <code>Long(17)</code>.
1224 * Values that cannot fit into a <code>Long</code> are returned as
1225 * <code>Double</code>s. This includes values with a fractional part,
1226 * infinite values, <code>NaN</code>, and the value -0.0.
1227 * <code>DecimalFormat</code> does <em>not</em> decide whether to
1228 * return a <code>Double</code> or a <code>Long</code> based on the
1229 * presence of a decimal separator in the source string. Doing so
1230 * would prevent integers that overflow the mantissa of a double,
1231 * such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
1232 * parsed accurately.
1233 * <p>
1234 * Callers may use the <code>Number</code> methods
1235 * <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
1236 * the type they want.
1237 * <li>If <code>isParseBigDecimal()</code> is true, values are returned
1238 * as <code>BigDecimal</code> objects. The values are the ones
1239 * constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1240 * for corresponding strings in locale-independent format. The
1241 * special cases negative and positive infinity and NaN are returned
1242 * as <code>Double</code> instances holding the values of the
1243 * corresponding <code>Double</code> constants.
1244 * </ul>
1245 * <p>
1246 * <code>DecimalFormat</code> parses all Unicode characters that represent
1247 * decimal digits, as defined by <code>Character.digit()</code>. In
1248 * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1249 * consecutive characters starting with the localized zero digit defined in
1250 * the <code>DecimalFormatSymbols</code> object.
1251 *
1252 * @param text the string to be parsed
1253 * @param pos A <code>ParsePosition</code> object with index and error
1254 * index information as described above.
1255 * @return the parsed value, or <code>null</code> if the parse fails
1256 * @exception NullPointerException if <code>text</code> or
1257 * <code>pos</code> is null.
1258 */
1259 public Number parse(String text, ParsePosition pos) {
1260 // special case NaN
1261 if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols.getNaN().length())) {
1262 pos.index = pos.index + symbols.getNaN().length();
1263 return new Double(Double.NaN);
1264 }
1265
1266 boolean[] status = new boolean[STATUS_LENGTH];
1267 if (!subparse(text, pos, positivePrefix, negativePrefix, digitList, false, status)) {
1268 return null;
1269 }
1270
1271 // special case INFINITY
1272 if (status[STATUS_INFINITE]) {
1273 if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1274 return new Double(Double.POSITIVE_INFINITY);
1275 } else {
1276 return new Double(Double.NEGATIVE_INFINITY);
1277 }
1278 }
1279
1280 if (multiplier == 0) {
1281 if (digitList.isZero()) {
1282 return new Double(Double.NaN);
1283 } else if (status[STATUS_POSITIVE]) {
1284 return new Double(Double.POSITIVE_INFINITY);
1285 } else {
1286 return new Double(Double.NEGATIVE_INFINITY);
1287 }
1288 }
1289
1290 if (isParseBigDecimal()) {
1291 BigDecimal bigDecimalResult = digitList.getBigDecimal();
1292
1293 if (multiplier != 1) {
1294 try {
1295 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier());
1296 }
1297 catch (ArithmeticException e) { // non-terminating decimal expansion
1298 bigDecimalResult = bigDecimalResult.divide(getBigDecimalMultiplier(), roundingMode);
1299 }
1300 }
1301
1302 if (!status[STATUS_POSITIVE]) {
1303 bigDecimalResult = bigDecimalResult.negate();
1304 }
1305 return bigDecimalResult;
1306 } else {
1307 boolean gotDouble = true;
1308 boolean gotLongMinimum = false;
1309 double doubleResult = 0.0;
1310 long longResult = 0;
1311
1312 // Finally, have DigitList parse the digits into a value.
1313 if (digitList.fitsIntoLong(status[STATUS_POSITIVE], isParseIntegerOnly())) {
1314 gotDouble = false;
1315 longResult = digitList.getLong();
1316 if (longResult < 0) { // got Long.MIN_VALUE
1317 gotLongMinimum = true;
1318 }
1319 } else {
1320 doubleResult = digitList.getDouble();
1321 }
1322
1323 // Divide by multiplier. We have to be careful here not to do
1324 // unneeded conversions between double and long.
1325 if (multiplier != 1) {
1326 if (gotDouble) {
1327 doubleResult /= multiplier;
1328 } else {
1329 // Avoid converting to double if we can
1330 if (longResult % multiplier == 0) {
1331 longResult /= multiplier;
1332 } else {
1333 doubleResult = ((double)longResult) / multiplier;
1334 gotDouble = true;
1335 }
1336 }
1337 }
1338
1339 if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
1340 doubleResult = -doubleResult;
1341 longResult = -longResult;
1342 }
1343
1344 // At this point, if we divided the result by the multiplier, the
1345 // result may fit into a long. We check for this case and return
1346 // a long if possible.
1347 // We must do this AFTER applying the negative (if appropriate)
1348 // in order to handle the case of LONG_MIN; otherwise, if we do
1349 // this with a positive value -LONG_MIN, the double is > 0, but
1350 // the long is < 0. We also must retain a double in the case of
1351 // -0.0, which will compare as == to a long 0 cast to a double
1352 // (bug 4162852).
1353 if (multiplier != 1 && gotDouble) {
1354 longResult = (long)doubleResult;
1355 gotDouble = ((doubleResult != (double)longResult) ||
1356 (doubleResult == 0.0 && 1/doubleResult < 0.0)) &&
1357 !isParseIntegerOnly();
1358 }
1359
1360 return gotDouble ?
1361 (Number)new Double(doubleResult) : (Number)new Long(longResult);
1362 }
1363 }
1364
1365 /**
1366 * Return a BigInteger multiplier.
1367 */
1368 private BigInteger getBigIntegerMultiplier() {
1369 if (bigIntegerMultiplier == null) {
1370 bigIntegerMultiplier = BigInteger.valueOf(multiplier);
1371 }
1372 return bigIntegerMultiplier;
1373 }
1374 private transient BigInteger bigIntegerMultiplier;
1375
1376 /**
1377 * Return a BigDecimal multiplier.
1378 */
1379 private BigDecimal getBigDecimalMultiplier() {
1380 if (bigDecimalMultiplier == null) {
1381 bigDecimalMultiplier = new BigDecimal(multiplier);
1382 }
1383 return bigDecimalMultiplier;
1384 }
1385 private transient BigDecimal bigDecimalMultiplier;
1386
1387 private static final int STATUS_INFINITE = 0;
1388 private static final int STATUS_POSITIVE = 1;
1389 private static final int STATUS_LENGTH = 2;
1390
1391 /**
1392 * Parse the given text into a number. The text is parsed beginning at
1393 * parsePosition, until an unparseable character is seen.
1394 * @param text The string to parse.
1395 * @param parsePosition The position at which to being parsing. Upon
1396 * return, the first unparseable character.
1397 * @param digits The DigitList to set to the parsed value.
1398 * @param isExponent If true, parse an exponent. This means no
1399 * infinite values and integer only.
1400 * @param status Upon return contains boolean status flags indicating
1401 * whether the value was infinite and whether it was positive.
1402 */
1403 private final boolean subparse(String text, ParsePosition parsePosition,
1404 String positivePrefix, String negativePrefix,
1405 DigitList digits, boolean isExponent,
1406 boolean status[]) {
1407 int position = parsePosition.index;
1408 int oldStart = parsePosition.index;
1409 int backup;
1410 boolean gotPositive, gotNegative;
1411
1412 // check for positivePrefix; take longest
1413 gotPositive = text.regionMatches(position, positivePrefix, 0,
1414 positivePrefix.length());
1415 gotNegative = text.regionMatches(position, negativePrefix, 0,
1416 negativePrefix.length());
1417
1418 if (gotPositive && gotNegative) {
1419 if (positivePrefix.length() > negativePrefix.length()) {
1420 gotNegative = false;
1421 } else if (positivePrefix.length() < negativePrefix.length()) {
1422 gotPositive = false;
1423 }
1424 }
1425
1426 if (gotPositive) {
1427 position += positivePrefix.length();
1428 } else if (gotNegative) {
1429 position += negativePrefix.length();
1430 } else {
1431 parsePosition.errorIndex = position;
1432 return false;
1433 }
1434
1435 // process digits or Inf, find decimal position
1436 status[STATUS_INFINITE] = false;
1437 if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
1438 symbols.getInfinity().length())) {
1439 position += symbols.getInfinity().length();
1440 status[STATUS_INFINITE] = true;
1441 } else {
1442 // We now have a string of digits, possibly with grouping symbols,
1443 // and decimal points. We want to process these into a DigitList.
1444 // We don't want to put a bunch of leading zeros into the DigitList
1445 // though, so we keep track of the location of the decimal point,
1446 // put only significant digits into the DigitList, and adjust the
1447 // exponent as needed.
1448
1449 digits.decimalAt = digits.count = 0;
1450 char zero = symbols.getZeroDigit();
1451 char decimal = isCurrencyFormat ?
1452 symbols.getMonetaryDecimalSeparator() :
1453 symbols.getDecimalSeparator();
1454 char grouping = symbols.getGroupingSeparator();
1455 String exponentString = symbols.getExponentSeparator();
1456 boolean sawDecimal = false;
1457 boolean sawExponent = false;
1458 boolean sawDigit = false;
1459 int exponent = 0; // Set to the exponent value, if any
1460
1461 // We have to track digitCount ourselves, because digits.count will
1462 // pin when the maximum allowable digits is reached.
1463 int digitCount = 0;
1464
1465 backup = -1;
1466 for (; position < text.length(); ++position) {
1467 char ch = text.charAt(position);
1468
1469 /* We recognize all digit ranges, not only the Latin digit range
1470 * '0'..'9'. We do so by using the Character.digit() method,
1471 * which converts a valid Unicode digit to the range 0..9.
1472 *
1473 * The character 'ch' may be a digit. If so, place its value
1474 * from 0 to 9 in 'digit'. First try using the locale digit,
1475 * which may or MAY NOT be a standard Unicode digit range. If
1476 * this fails, try using the standard Unicode digit ranges by
1477 * calling Character.digit(). If this also fails, digit will
1478 * have a value outside the range 0..9.
1479 */
1480 int digit = ch - zero;
1481 if (digit < 0 || digit > 9) {
1482 digit = Character.digit(ch, 10);
1483 }
1484
1485 if (digit == 0) {
1486 // Cancel out backup setting (see grouping handler below)
1487 backup = -1; // Do this BEFORE continue statement below!!!
1488 sawDigit = true;
1489
1490 // Handle leading zeros
1491 if (digits.count == 0) {
1492 // Ignore leading zeros in integer part of number.
1493 if (!sawDecimal) {
1494 continue;
1495 }
1496
1497 // If we have seen the decimal, but no significant
1498 // digits yet, then we account for leading zeros by
1499 // decrementing the digits.decimalAt into negative
1500 // values.
1501 --digits.decimalAt;
1502 } else {
1503 ++digitCount;
1504 digits.append((char)(digit + '0'));
1505 }
1506 } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
1507 sawDigit = true;
1508 ++digitCount;
1509 digits.append((char)(digit + '0'));
1510
1511 // Cancel out backup setting (see grouping handler below)
1512 backup = -1;
1513 } else if (!isExponent && ch == decimal) {
1514 // If we're only parsing integers, or if we ALREADY saw the
1515 // decimal, then don't parse this one.
1516 if (isParseIntegerOnly() || sawDecimal) {
1517 break;
1518 }
1519 digits.decimalAt = digitCount; // Not digits.count!
1520 sawDecimal = true;
1521 } else if (!isExponent && ch == grouping && isGroupingUsed()) {
1522 if (sawDecimal) {
1523 break;
1524 }
1525 // Ignore grouping characters, if we are using them, but
1526 // require that they be followed by a digit. Otherwise
1527 // we backup and reprocess them.
1528 backup = position;
1529 } else if (!isExponent && text.regionMatches(position, exponentString, 0, exponentString.length())
1530 && !sawExponent) {
1531 // Process the exponent by recursively calling this method.
1532 ParsePosition pos = new ParsePosition(position + exponentString.length());
1533 boolean[] stat = new boolean[STATUS_LENGTH];
1534 DigitList exponentDigits = new DigitList();
1535
1536 if (subparse(text, pos, "", Character.toString(symbols.getMinusSign()), exponentDigits, true, stat) &&
1537 exponentDigits.fitsIntoLong(stat[STATUS_POSITIVE], true)) {
1538 position = pos.index; // Advance past the exponent
1539 exponent = (int)exponentDigits.getLong();
1540 if (!stat[STATUS_POSITIVE]) {
1541 exponent = -exponent;
1542 }
1543 sawExponent = true;
1544 }
1545 break; // Whether we fail or succeed, we exit this loop
1546 }
1547 else {
1548 break;
1549 }
1550 }
1551
1552 if (backup != -1) {
1553 position = backup;
1554 }
1555
1556 // If there was no decimal point we have an integer
1557 if (!sawDecimal) {
1558 digits.decimalAt = digitCount; // Not digits.count!
1559 }
1560
1561 // Adjust for exponent, if any
1562 digits.decimalAt += exponent;
1563
1564 // If none of the text string was recognized. For example, parse
1565 // "x" with pattern "#0.00" (return index and error index both 0)
1566 // parse "$" with pattern "$#0.00". (return index 0 and error
1567 // index 1).
1568 if (!sawDigit && digitCount == 0) {
1569 parsePosition.index = oldStart;
1570 parsePosition.errorIndex = oldStart;
1571 return false;
1572 }
1573 }
1574
1575 // check for suffix
1576 if (!isExponent) {
1577 if (gotPositive) {
1578 gotPositive = text.regionMatches(position,positiveSuffix,0,
1579 positiveSuffix.length());
1580 }
1581 if (gotNegative) {
1582 gotNegative = text.regionMatches(position,negativeSuffix,0,
1583 negativeSuffix.length());
1584 }
1585
1586 // if both match, take longest
1587 if (gotPositive && gotNegative) {
1588 if (positiveSuffix.length() > negativeSuffix.length()) {
1589 gotNegative = false;
1590 } else if (positiveSuffix.length() < negativeSuffix.length()) {
1591 gotPositive = false;
1592 }
1593 }
1594
1595 // fail if neither or both
1596 if (gotPositive == gotNegative) {
1597 parsePosition.errorIndex = position;
1598 return false;
1599 }
1600
1601 parsePosition.index = position +
1602 (gotPositive ? positiveSuffix.length() : negativeSuffix.length()); // mark success!
1603 } else {
1604 parsePosition.index = position;
1605 }
1606
1607 status[STATUS_POSITIVE] = gotPositive;
1608 if (parsePosition.index == oldStart) {
1609 parsePosition.errorIndex = position;
1610 return false;
1611 }
1612 return true;
1613 }
1614
1615 /**
1616 * Returns a copy of the decimal format symbols, which is generally not
1617 * changed by the programmer or user.
1618 * @return a copy of the desired DecimalFormatSymbols
1619 * @see java.text.DecimalFormatSymbols
1620 */
1621 public DecimalFormatSymbols getDecimalFormatSymbols() {
1622 try {
1623 // don't allow multiple references
1624 return (DecimalFormatSymbols) symbols.clone();
1625 } catch (Exception foo) {
1626 return null; // should never happen
1627 }
1628 }
1629
1630
1631 /**
1632 * Sets the decimal format symbols, which is generally not changed
1633 * by the programmer or user.
1634 * @param newSymbols desired DecimalFormatSymbols
1635 * @see java.text.DecimalFormatSymbols
1636 */
1637 public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
1638 try {
1639 // don't allow multiple references
1640 symbols = (DecimalFormatSymbols) newSymbols.clone();
1641 expandAffixes();
1642 } catch (Exception foo) {
1643 // should never happen
1644 }
1645 }
1646
1647 /**
1648 * Get the positive prefix.
1649 * <P>Examples: +123, $123, sFr123
1650 */
1651 public String getPositivePrefix () {
1652 return positivePrefix;
1653 }
1654
1655 /**
1656 * Set the positive prefix.
1657 * <P>Examples: +123, $123, sFr123
1658 */
1659 public void setPositivePrefix (String newValue) {
1660 positivePrefix = newValue;
1661 posPrefixPattern = null;
1662 positivePrefixFieldPositions = null;
1663 }
1664
1665 /**
1666 * Returns the FieldPositions of the fields in the prefix used for
1667 * positive numbers. This is not used if the user has explicitly set
1668 * a positive prefix via <code>setPositivePrefix</code>. This is
1669 * lazily created.
1670 *
1671 * @return FieldPositions in positive prefix
1672 */
1673 private FieldPosition[] getPositivePrefixFieldPositions() {
1674 if (positivePrefixFieldPositions == null) {
1675 if (posPrefixPattern != null) {
1676 positivePrefixFieldPositions = expandAffix(posPrefixPattern);
1677 }
1678 else {
1679 positivePrefixFieldPositions = EmptyFieldPositionArray;
1680 }
1681 }
1682 return positivePrefixFieldPositions;
1683 }
1684
1685 /**
1686 * Get the negative prefix.
1687 * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1688 */
1689 public String getNegativePrefix () {
1690 return negativePrefix;
1691 }
1692
1693 /**
1694 * Set the negative prefix.
1695 * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1696 */
1697 public void setNegativePrefix (String newValue) {
1698 negativePrefix = newValue;
1699 negPrefixPattern = null;
1700 }
1701
1702 /**
1703 * Returns the FieldPositions of the fields in the prefix used for
1704 * negative numbers. This is not used if the user has explicitly set
1705 * a negative prefix via <code>setNegativePrefix</code>. This is
1706 * lazily created.
1707 *
1708 * @return FieldPositions in positive prefix
1709 */
1710 private FieldPosition[] getNegativePrefixFieldPositions() {
1711 if (negativePrefixFieldPositions == null) {
1712 if (negPrefixPattern != null) {
1713 negativePrefixFieldPositions = expandAffix(negPrefixPattern);
1714 }
1715 else {
1716 negativePrefixFieldPositions = EmptyFieldPositionArray;
1717 }
1718 }
1719 return negativePrefixFieldPositions;
1720 }
1721
1722 /**
1723 * Get the positive suffix.
1724 * <P>Example: 123%
1725 */
1726 public String getPositiveSuffix () {
1727 return positiveSuffix;
1728 }
1729
1730 /**
1731 * Set the positive suffix.
1732 * <P>Example: 123%
1733 */
1734 public void setPositiveSuffix (String newValue) {
1735 positiveSuffix = newValue;
1736 posSuffixPattern = null;
1737 }
1738
1739 /**
1740 * Returns the FieldPositions of the fields in the suffix used for
1741 * positive numbers. This is not used if the user has explicitly set
1742 * a positive suffix via <code>setPositiveSuffix</code>. This is
1743 * lazily created.
1744 *
1745 * @return FieldPositions in positive prefix
1746 */
1747 private FieldPosition[] getPositiveSuffixFieldPositions() {
1748 if (positiveSuffixFieldPositions == null) {
1749 if (posSuffixPattern != null) {
1750 positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
1751 }
1752 else {
1753 positiveSuffixFieldPositions = EmptyFieldPositionArray;
1754 }
1755 }
1756 return positiveSuffixFieldPositions;
1757 }
1758
1759 /**
1760 * Get the negative suffix.
1761 * <P>Examples: -123%, ($123) (with positive suffixes)
1762 */
1763 public String getNegativeSuffix () {
1764 return negativeSuffix;
1765 }
1766
1767 /**
1768 * Set the negative suffix.
1769 * <P>Examples: 123%
1770 */
1771 public void setNegativeSuffix (String newValue) {
1772 negativeSuffix = newValue;
1773 negSuffixPattern = null;
1774 }
1775
1776 /**
1777 * Returns the FieldPositions of the fields in the suffix used for
1778 * negative numbers. This is not used if the user has explicitly set
1779 * a negative suffix via <code>setNegativeSuffix</code>. This is
1780 * lazily created.
1781 *
1782 * @return FieldPositions in positive prefix
1783 */
1784 private FieldPosition[] getNegativeSuffixFieldPositions() {
1785 if (negativeSuffixFieldPositions == null) {
1786 if (negSuffixPattern != null) {
1787 negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
1788 }
1789 else {
1790 negativeSuffixFieldPositions = EmptyFieldPositionArray;
1791 }
1792 }
1793 return negativeSuffixFieldPositions;
1794 }
1795
1796 /**
1797 * Gets the multiplier for use in percent, per mille, and similar
1798 * formats.
1799 *
1800 * @see #setMultiplier(int)
1801 */
1802 public int getMultiplier () {
1803 return multiplier;
1804 }
1805
1806 /**
1807 * Sets the multiplier for use in percent, per mille, and similar
1808 * formats.
1809 * For a percent format, set the multiplier to 100 and the suffixes to
1810 * have '%' (for Arabic, use the Arabic percent sign).
1811 * For a per mille format, set the multiplier to 1000 and the suffixes to
1812 * have '&#92;u2030'.
1813 *
1814 * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
1815 * "123" is parsed into 1.23.
1816 *
1817 * @see #getMultiplier
1818 */
1819 public void setMultiplier (int newValue) {
1820 multiplier = newValue;
1821 bigDecimalMultiplier = null;
1822 bigIntegerMultiplier = null;
1823 }
1824
1825 /**
1826 * Return the grouping size. Grouping size is the number of digits between
1827 * grouping separators in the integer portion of a number. For example,
1828 * in the number "123,456.78", the grouping size is 3.
1829 * @see #setGroupingSize
1830 * @see java.text.NumberFormat#isGroupingUsed
1831 * @see java.text.DecimalFormatSymbols#getGroupingSeparator
1832 */
1833 public int getGroupingSize () {
1834 return groupingSize;
1835 }
1836
1837 /**
1838 * Set the grouping size. Grouping size is the number of digits between
1839 * grouping separators in the integer portion of a number. For example,
1840 * in the number "123,456.78", the grouping size is 3.
1841 * <br>
1842 * The value passed in is converted to a byte, which may lose information.
1843 * @see #getGroupingSize
1844 * @see java.text.NumberFormat#setGroupingUsed
1845 * @see java.text.DecimalFormatSymbols#setGroupingSeparator
1846 */
1847 public void setGroupingSize (int newValue) {
1848 groupingSize = (byte)newValue;
1849 }
1850
1851 /**
1852 * Allows you to get the behavior of the decimal separator with integers.
1853 * (The decimal separator will always appear with decimals.)
1854 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1855 */
1856 public boolean isDecimalSeparatorAlwaysShown() {
1857 return decimalSeparatorAlwaysShown;
1858 }
1859
1860 /**
1861 * Allows you to set the behavior of the decimal separator with integers.
1862 * (The decimal separator will always appear with decimals.)
1863 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1864 */
1865 public void setDecimalSeparatorAlwaysShown(boolean newValue) {
1866 decimalSeparatorAlwaysShown = newValue;
1867 }
1868
1869 /**
1870 * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1871 * method returns <code>BigDecimal</code>. The default value is false.
1872 * @see #setParseBigDecimal
1873 * @since 1.5
1874 */
1875 public boolean isParseBigDecimal() {
1876 return parseBigDecimal;
1877 }
1878
1879 /**
1880 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1881 * method returns <code>BigDecimal</code>.
1882 * @see #isParseBigDecimal
1883 * @since 1.5
1884 */
1885 public void setParseBigDecimal(boolean newValue) {
1886 parseBigDecimal = newValue;
1887 }
1888
1889 /**
1890 * Standard override; no change in semantics.
1891 */
1892 public Object clone() {
1893 try {
1894 DecimalFormat other = (DecimalFormat) super.clone();
1895 other.symbols = (DecimalFormatSymbols) symbols.clone();
1896 other.digitList = (DigitList) digitList.clone();
1897 return other;
1898 } catch (Exception e) {
1899 throw new InternalError();
1900 }
1901 }
1902
1903 /**
1904 * Overrides equals
1905 */
1906 public boolean equals(Object obj)
1907 {
1908 if (obj == null) return false;
1909 if (!super.equals(obj)) return false; // super does class check
1910 DecimalFormat other = (DecimalFormat) obj;
1911 return ((posPrefixPattern == other.posPrefixPattern &&
1912 positivePrefix.equals(other.positivePrefix))
1913 || (posPrefixPattern != null &&
1914 posPrefixPattern.equals(other.posPrefixPattern)))
1915 && ((posSuffixPattern == other.posSuffixPattern &&
1916 positiveSuffix.equals(other.positiveSuffix))
1917 || (posSuffixPattern != null &&
1918 posSuffixPattern.equals(other.posSuffixPattern)))
1919 && ((negPrefixPattern == other.negPrefixPattern &&
1920 negativePrefix.equals(other.negativePrefix))
1921 || (negPrefixPattern != null &&
1922 negPrefixPattern.equals(other.negPrefixPattern)))
1923 && ((negSuffixPattern == other.negSuffixPattern &&
1924 negativeSuffix.equals(other.negativeSuffix))
1925 || (negSuffixPattern != null &&
1926 negSuffixPattern.equals(other.negSuffixPattern)))
1927 && multiplier == other.multiplier
1928 && groupingSize == other.groupingSize
1929 && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1930 && parseBigDecimal == other.parseBigDecimal
1931 && useExponentialNotation == other.useExponentialNotation
1932 && (!useExponentialNotation ||
1933 minExponentDigits == other.minExponentDigits)
1934 && maximumIntegerDigits == other.maximumIntegerDigits
1935 && minimumIntegerDigits == other.minimumIntegerDigits
1936 && maximumFractionDigits == other.maximumFractionDigits
1937 && minimumFractionDigits == other.minimumFractionDigits
1938 && roundingMode == other.roundingMode
1939 && symbols.equals(other.symbols);
1940 }
1941
1942 /**
1943 * Overrides hashCode
1944 */
1945 public int hashCode() {
1946 return super.hashCode() * 37 + positivePrefix.hashCode();
1947 // just enough fields for a reasonable distribution
1948 }
1949
1950 /**
1951 * Synthesizes a pattern string that represents the current state
1952 * of this Format object.
1953 * @see #applyPattern
1954 */
1955 public String toPattern() {
1956 return toPattern( false );
1957 }
1958
1959 /**
1960 * Synthesizes a localized pattern string that represents the current
1961 * state of this Format object.
1962 * @see #applyPattern
1963 */
1964 public String toLocalizedPattern() {
1965 return toPattern( true );
1966 }
1967
1968 /**
1969 * Expand the affix pattern strings into the expanded affix strings. If any
1970 * affix pattern string is null, do not expand it. This method should be
1971 * called any time the symbols or the affix patterns change in order to keep
1972 * the expanded affix strings up to date.
1973 */
1974 private void expandAffixes() {
1975 // Reuse one StringBuffer for better performance
1976 StringBuffer buffer = new StringBuffer();
1977 if (posPrefixPattern != null) {
1978 positivePrefix = expandAffix(posPrefixPattern, buffer);
1979 positivePrefixFieldPositions = null;
1980 }
1981 if (posSuffixPattern != null) {
1982 positiveSuffix = expandAffix(posSuffixPattern, buffer);
1983 positiveSuffixFieldPositions = null;
1984 }
1985 if (negPrefixPattern != null) {
1986 negativePrefix = expandAffix(negPrefixPattern, buffer);
1987 negativePrefixFieldPositions = null;
1988 }
1989 if (negSuffixPattern != null) {
1990 negativeSuffix = expandAffix(negSuffixPattern, buffer);
1991 negativeSuffixFieldPositions = null;
1992 }
1993 }
1994
1995 /**
1996 * Expand an affix pattern into an affix string. All characters in the
1997 * pattern are literal unless prefixed by QUOTE. The following characters
1998 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
1999 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2000 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2001 * currency code. Any other character after a QUOTE represents itself.
2002 * QUOTE must be followed by another character; QUOTE may not occur by
2003 * itself at the end of the pattern.
2004 *
2005 * @param pattern the non-null, possibly empty pattern
2006 * @param buffer a scratch StringBuffer; its contents will be lost
2007 * @return the expanded equivalent of pattern
2008 */
2009 private String expandAffix(String pattern, StringBuffer buffer) {
2010 buffer.setLength(0);
2011 for (int i=0; i<pattern.length(); ) {
2012 char c = pattern.charAt(i++);
2013 if (c == QUOTE) {
2014 c = pattern.charAt(i++);
2015 switch (c) {
2016 case CURRENCY_SIGN:
2017 if (i<pattern.length() &&
2018 pattern.charAt(i) == CURRENCY_SIGN) {
2019 ++i;
2020 buffer.append(symbols.getInternationalCurrencySymbol());
2021 } else {
2022 buffer.append(symbols.getCurrencySymbol());
2023 }
2024 continue;
2025 case PATTERN_PERCENT:
2026 c = symbols.getPercent();
2027 break;
2028 case PATTERN_PER_MILLE:
2029 c = symbols.getPerMill();
2030 break;
2031 case PATTERN_MINUS:
2032 c = symbols.getMinusSign();
2033 break;
2034 }
2035 }
2036 buffer.append(c);
2037 }
2038 return buffer.toString();
2039 }
2040
2041 /**
2042 * Expand an affix pattern into an array of FieldPositions describing
2043 * how the pattern would be expanded.
2044 * All characters in the
2045 * pattern are literal unless prefixed by QUOTE. The following characters
2046 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2047 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2048 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2049 * currency code. Any other character after a QUOTE represents itself.
2050 * QUOTE must be followed by another character; QUOTE may not occur by
2051 * itself at the end of the pattern.
2052 *
2053 * @param pattern the non-null, possibly empty pattern
2054 * @return FieldPosition array of the resulting fields.
2055 */
2056 private FieldPosition[] expandAffix(String pattern) {
2057 ArrayList positions = null;
2058 int stringIndex = 0;
2059 for (int i=0; i<pattern.length(); ) {
2060 char c = pattern.charAt(i++);
2061 if (c == QUOTE) {
2062 int field = -1;
2063 Format.Field fieldID = null;
2064 c = pattern.charAt(i++);
2065 switch (c) {
2066 case CURRENCY_SIGN:
2067 String string;
2068 if (i<pattern.length() &&
2069 pattern.charAt(i) == CURRENCY_SIGN) {
2070 ++i;
2071 string = symbols.getInternationalCurrencySymbol();
2072 } else {
2073 string = symbols.getCurrencySymbol();
2074 }
2075 if (string.length() > 0) {
2076 if (positions == null) {
2077 positions = new ArrayList(2);
2078 }
2079 FieldPosition fp = new FieldPosition(Field.CURRENCY);
2080 fp.setBeginIndex(stringIndex);
2081 fp.setEndIndex(stringIndex + string.length());
2082 positions.add(fp);
2083 stringIndex += string.length();
2084 }
2085 continue;
2086 case PATTERN_PERCENT:
2087 c = symbols.getPercent();
2088 field = -1;
2089 fieldID = Field.PERCENT;
2090 break;
2091 case PATTERN_PER_MILLE:
2092 c = symbols.getPerMill();
2093 field = -1;
2094 fieldID = Field.PERMILLE;
2095 break;
2096 case PATTERN_MINUS:
2097 c = symbols.getMinusSign();
2098 field = -1;
2099 fieldID = Field.SIGN;
2100 break;
2101 }
2102 if (fieldID != null) {
2103 if (positions == null) {
2104 positions = new ArrayList(2);
2105 }
2106 FieldPosition fp = new FieldPosition(fieldID, field);
2107 fp.setBeginIndex(stringIndex);
2108 fp.setEndIndex(stringIndex + 1);
2109 positions.add(fp);
2110 }
2111 }
2112 stringIndex++;
2113 }
2114 if (positions != null) {
2115 return (FieldPosition[])positions.toArray(EmptyFieldPositionArray);
2116 }
2117 return EmptyFieldPositionArray;
2118 }
2119
2120 /**
2121 * Appends an affix pattern to the given StringBuffer, quoting special
2122 * characters as needed. Uses the internal affix pattern, if that exists,
2123 * or the literal affix, if the internal affix pattern is null. The
2124 * appended string will generate the same affix pattern (or literal affix)
2125 * when passed to toPattern().
2126 *
2127 * @param buffer the affix string is appended to this
2128 * @param affixPattern a pattern such as posPrefixPattern; may be null
2129 * @param expAffix a corresponding expanded affix, such as positivePrefix.
2130 * Ignored unless affixPattern is null. If affixPattern is null, then
2131 * expAffix is appended as a literal affix.
2132 * @param localized true if the appended pattern should contain localized
2133 * pattern characters; otherwise, non-localized pattern chars are appended
2134 */
2135 private void appendAffix(StringBuffer buffer, String affixPattern,
2136 String expAffix, boolean localized) {
2137 if (affixPattern == null) {
2138 appendAffix(buffer, expAffix, localized);
2139 } else {
2140 int i;
2141 for (int pos=0; pos<affixPattern.length(); pos=i) {
2142 i = affixPattern.indexOf(QUOTE, pos);
2143 if (i < 0) {
2144 appendAffix(buffer, affixPattern.substring(pos), localized);
2145 break;
2146 }
2147 if (i > pos) {
2148 appendAffix(buffer, affixPattern.substring(pos, i), localized);
2149 }
2150 char c = affixPattern.charAt(++i);
2151 ++i;
2152 if (c == QUOTE) {
2153 buffer.append(c);
2154 // Fall through and append another QUOTE below
2155 } else if (c == CURRENCY_SIGN &&
2156 i<affixPattern.length() &&
2157 affixPattern.charAt(i) == CURRENCY_SIGN) {
2158 ++i;
2159 buffer.append(c);
2160 // Fall through and append another CURRENCY_SIGN below
2161 } else if (localized) {
2162 switch (c) {
2163 case PATTERN_PERCENT:
2164 c = symbols.getPercent();
2165 break;
2166 case PATTERN_PER_MILLE:
2167 c = symbols.getPerMill();
2168 break;
2169 case PATTERN_MINUS:
2170 c = symbols.getMinusSign();
2171 break;
2172 }
2173 }
2174 buffer.append(c);
2175 }
2176 }
2177 }
2178
2179 /**
2180 * Append an affix to the given StringBuffer, using quotes if
2181 * there are special characters. Single quotes themselves must be
2182 * escaped in either case.
2183 */
2184 private void appendAffix(StringBuffer buffer, String affix, boolean localized) {
2185 boolean needQuote;
2186 if (localized) {
2187 needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
2188 || affix.indexOf(symbols.getGroupingSeparator()) >= 0
2189 || affix.indexOf(symbols.getDecimalSeparator()) >= 0
2190 || affix.indexOf(symbols.getPercent()) >= 0
2191 || affix.indexOf(symbols.getPerMill()) >= 0
2192 || affix.indexOf(symbols.getDigit()) >= 0
2193 || affix.indexOf(symbols.getPatternSeparator()) >= 0
2194 || affix.indexOf(symbols.getMinusSign()) >= 0
2195 || affix.indexOf(CURRENCY_SIGN) >= 0;
2196 }
2197 else {
2198 needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
2199 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
2200 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
2201 || affix.indexOf(PATTERN_PERCENT) >= 0
2202 || affix.indexOf(PATTERN_PER_MILLE) >= 0
2203 || affix.indexOf(PATTERN_DIGIT) >= 0
2204 || affix.indexOf(PATTERN_SEPARATOR) >= 0
2205 || affix.indexOf(PATTERN_MINUS) >= 0
2206 || affix.indexOf(CURRENCY_SIGN) >= 0;
2207 }
2208 if (needQuote) buffer.append('\'');
2209 if (affix.indexOf('\'') < 0) buffer.append(affix);
2210 else {
2211 for (int j=0; j<affix.length(); ++j) {
2212 char c = affix.charAt(j);
2213 buffer.append(c);
2214 if (c == '\'') buffer.append(c);
2215 }
2216 }
2217 if (needQuote) buffer.append('\'');
2218 }
2219
2220 /**
2221 * Does the real work of generating a pattern. */
2222 private String toPattern(boolean localized) {
2223 StringBuffer result = new StringBuffer();
2224 for (int j = 1; j >= 0; --j) {
2225 if (j == 1)
2226 appendAffix(result, posPrefixPattern, positivePrefix, localized);
2227 else appendAffix(result, negPrefixPattern, negativePrefix, localized);
2228 int i;
2229 int digitCount = useExponentialNotation
2230 ? getMaximumIntegerDigits()
2231 : Math.max(groupingSize, getMinimumIntegerDigits())+1;
2232 for (i = digitCount; i > 0; --i) {
2233 if (i != digitCount && isGroupingUsed() && groupingSize != 0 &&
2234 i % groupingSize == 0) {
2235 result.append(localized ? symbols.getGroupingSeparator() :
2236 PATTERN_GROUPING_SEPARATOR);
2237 }
2238 result.append(i <= getMinimumIntegerDigits()
2239 ? (localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT)
2240 : (localized ? symbols.getDigit() : PATTERN_DIGIT));
2241 }
2242 if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown)
2243 result.append(localized ? symbols.getDecimalSeparator() :
2244 PATTERN_DECIMAL_SEPARATOR);
2245 for (i = 0; i < getMaximumFractionDigits(); ++i) {
2246 if (i < getMinimumFractionDigits()) {
2247 result.append(localized ? symbols.getZeroDigit() :
2248 PATTERN_ZERO_DIGIT);
2249 } else {
2250 result.append(localized ? symbols.getDigit() :
2251 PATTERN_DIGIT);
2252 }
2253 }
2254 if (useExponentialNotation)
2255 {
2256 result.append(localized ? symbols.getExponentSeparator() :
2257 PATTERN_EXPONENT);
2258 for (i=0; i<minExponentDigits; ++i)
2259 result.append(localized ? symbols.getZeroDigit() :
2260 PATTERN_ZERO_DIGIT);
2261 }
2262 if (j == 1) {
2263 appendAffix(result, posSuffixPattern, positiveSuffix, localized);
2264 if ((negSuffixPattern == posSuffixPattern && // n == p == null
2265 negativeSuffix.equals(positiveSuffix))
2266 || (negSuffixPattern != null &&
2267 negSuffixPattern.equals(posSuffixPattern))) {
2268 if ((negPrefixPattern != null && posPrefixPattern != null &&
2269 negPrefixPattern.equals("'-" + posPrefixPattern)) ||
2270 (negPrefixPattern == posPrefixPattern && // n == p == null
2271 negativePrefix.equals(symbols.getMinusSign() + positivePrefix)))
2272 break;
2273 }
2274 result.append(localized ? symbols.getPatternSeparator() :
2275 PATTERN_SEPARATOR);
2276 } else appendAffix(result, negSuffixPattern, negativeSuffix, localized);
2277 }
2278 return result.toString();
2279 }
2280
2281 /**
2282 * Apply the given pattern to this Format object. A pattern is a
2283 * short-hand specification for the various formatting properties.
2284 * These properties can also be changed individually through the
2285 * various setter methods.
2286 * <p>
2287 * There is no limit to integer digits set
2288 * by this routine, since that is the typical end-user desire;
2289 * use setMaximumInteger if you want to set a real value.
2290 * For negative numbers, use a second pattern, separated by a semicolon
2291 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2292 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2293 * a maximum of 2 fraction digits.
2294 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2295 * parentheses.
2296 * <p>In negative patterns, the minimum and maximum counts are ignored;
2297 * these are presumed to be set in the positive pattern.
2298 *
2299 * @exception NullPointerException if <code>pattern</code> is null
2300 * @exception IllegalArgumentException if the given pattern is invalid.
2301 */
2302 public void applyPattern(String pattern) {
2303 applyPattern(pattern, false);
2304 }
2305
2306 /**
2307 * Apply the given pattern to this Format object. The pattern
2308 * is assumed to be in a localized notation. A pattern is a
2309 * short-hand specification for the various formatting properties.
2310 * These properties can also be changed individually through the
2311 * various setter methods.
2312 * <p>
2313 * There is no limit to integer digits set
2314 * by this routine, since that is the typical end-user desire;
2315 * use setMaximumInteger if you want to set a real value.
2316 * For negative numbers, use a second pattern, separated by a semicolon
2317 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2318 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2319 * a maximum of 2 fraction digits.
2320 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2321 * parentheses.
2322 * <p>In negative patterns, the minimum and maximum counts are ignored;
2323 * these are presumed to be set in the positive pattern.
2324 *
2325 * @exception NullPointerException if <code>pattern</code> is null
2326 * @exception IllegalArgumentException if the given pattern is invalid.
2327 */
2328 public void applyLocalizedPattern(String pattern) {
2329 applyPattern(pattern, true);
2330 }
2331
2332 /**
2333 * Does the real work of applying a pattern.
2334 */
2335 private void applyPattern(String pattern, boolean localized) {
2336 char zeroDigit = PATTERN_ZERO_DIGIT;
2337 char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
2338 char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;
2339 char percent = PATTERN_PERCENT;
2340 char perMill = PATTERN_PER_MILLE;
2341 char digit = PATTERN_DIGIT;
2342 char separator = PATTERN_SEPARATOR;
2343 String exponent = PATTERN_EXPONENT;
2344 char minus = PATTERN_MINUS;
2345 if (localized) {
2346 zeroDigit = symbols.getZeroDigit();
2347 groupingSeparator = symbols.getGroupingSeparator();
2348 decimalSeparator = symbols.getDecimalSeparator();
2349 percent = symbols.getPercent();
2350 perMill = symbols.getPerMill();
2351 digit = symbols.getDigit();
2352 separator = symbols.getPatternSeparator();
2353 exponent = symbols.getExponentSeparator();
2354 minus = symbols.getMinusSign();
2355 }
2356 boolean gotNegative = false;
2357 decimalSeparatorAlwaysShown = false;
2358 isCurrencyFormat = false;
2359 useExponentialNotation = false;
2360
2361 // Two variables are used to record the subrange of the pattern
2362 // occupied by phase 1. This is used during the processing of the
2363 // second pattern (the one representing negative numbers) to ensure
2364 // that no deviation exists in phase 1 between the two patterns.
2365 int phaseOneStart = 0;
2366 int phaseOneLength = 0;
2367
2368 int start = 0;
2369 for (int j = 1; j >= 0 && start < pattern.length(); --j) {
2370 boolean inQuote = false;
2371 StringBuffer prefix = new StringBuffer();
2372 StringBuffer suffix = new StringBuffer();
2373 int decimalPos = -1;
2374 int multiplier = 1;
2375 int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
2376 byte groupingCount = -1;
2377
2378 // The phase ranges from 0 to 2. Phase 0 is the prefix. Phase 1 is
2379 // the section of the pattern with digits, decimal separator,
2380 // grouping characters. Phase 2 is the suffix. In phases 0 and 2,
2381 // percent, per mille, and currency symbols are recognized and
2382 // translated. The separation of the characters into phases is
2383 // strictly enforced; if phase 1 characters are to appear in the
2384 // suffix, for example, they must be quoted.
2385 int phase = 0;
2386
2387 // The affix is either the prefix or the suffix.
2388 StringBuffer affix = prefix;
2389
2390 for (int pos = start; pos < pattern.length(); ++pos) {
2391 char ch = pattern.charAt(pos);
2392 switch (phase) {
2393 case 0:
2394 case 2:
2395 // Process the prefix / suffix characters
2396 if (inQuote) {
2397 // A quote within quotes indicates either the closing
2398 // quote or two quotes, which is a quote literal. That
2399 // is, we have the second quote in 'do' or 'don''t'.
2400 if (ch == QUOTE) {
2401 if ((pos+1) < pattern.length() &&
2402 pattern.charAt(pos+1) == QUOTE) {
2403 ++pos;
2404 affix.append("''"); // 'don''t'
2405 } else {
2406 inQuote = false; // 'do'
2407 }
2408 continue;
2409 }
2410 } else {
2411 // Process unquoted characters seen in prefix or suffix
2412 // phase.
2413 if (ch == digit ||
2414 ch == zeroDigit ||
2415 ch == groupingSeparator ||
2416 ch == decimalSeparator) {
2417 phase = 1;
2418 if (j == 1) {
2419 phaseOneStart = pos;
2420 }
2421 --pos; // Reprocess this character
2422 continue;
2423 } else if (ch == CURRENCY_SIGN) {
2424 // Use lookahead to determine if the currency sign
2425 // is doubled or not.
2426 boolean doubled = (pos + 1) < pattern.length() &&
2427 pattern.charAt(pos + 1) == CURRENCY_SIGN;
2428 if (doubled) { // Skip over the doubled character
2429 ++pos;
2430 }
2431 isCurrencyFormat = true;
2432 affix.append(doubled ? "'\u00A4\u00A4" : "'\u00A4");
2433 continue;
2434 } else if (ch == QUOTE) {
2435 // A quote outside quotes indicates either the
2436 // opening quote or two quotes, which is a quote
2437 // literal. That is, we have the first quote in 'do'
2438 // or o''clock.
2439 if (ch == QUOTE) {
2440 if ((pos+1) < pattern.length() &&
2441 pattern.charAt(pos+1) == QUOTE) {
2442 ++pos;
2443 affix.append("''"); // o''clock
2444 } else {
2445 inQuote = true; // 'do'
2446 }
2447 continue;
2448 }
2449 } else if (ch == separator) {
2450 // Don't allow separators before we see digit
2451 // characters of phase 1, and don't allow separators
2452 // in the second pattern (j == 0).
2453 if (phase == 0 || j == 0) {
2454 throw new IllegalArgumentException("Unquoted special character '" +
2455 ch + "' in pattern \"" + pattern + '"');
2456 }
2457 start = pos + 1;
2458 pos = pattern.length();
2459 continue;
2460 }
2461
2462 // Next handle characters which are appended directly.
2463 else if (ch == percent) {
2464 if (multiplier != 1) {
2465 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
2466 pattern + '"');
2467 }
2468 multiplier = 100;
2469 affix.append("'%");
2470 continue;
2471 } else if (ch == perMill) {
2472 if (multiplier != 1) {
2473 throw new IllegalArgumentException("Too many percent/per mille characters in pattern \"" +
2474 pattern + '"');
2475 }
2476 multiplier = 1000;
2477 affix.append("'\u2030");
2478 continue;
2479 } else if (ch == minus) {
2480 affix.append("'-");
2481 continue;
2482 }
2483 }
2484 // Note that if we are within quotes, or if this is an
2485 // unquoted, non-special character, then we usually fall
2486 // through to here.
2487 affix.append(ch);
2488 break;
2489
2490 case 1:
2491 // Phase one must be identical in the two sub-patterns. We
2492 // enforce this by doing a direct comparison. While
2493 // processing the first sub-pattern, we just record its
2494 // length. While processing the second, we compare
2495 // characters.
2496 if (j == 1) {
2497 ++phaseOneLength;
2498 } else {
2499 if (--phaseOneLength == 0) {
2500 phase = 2;
2501 affix = suffix;
2502 }
2503 continue;
2504 }
2505
2506 // Process the digits, decimal, and grouping characters. We
2507 // record five pieces of information. We expect the digits
2508 // to occur in the pattern ####0000.####, and we record the
2509 // number of left digits, zero (central) digits, and right
2510 // digits. The position of the last grouping character is
2511 // recorded (should be somewhere within the first two blocks
2512 // of characters), as is the position of the decimal point,
2513 // if any (should be in the zero digits). If there is no
2514 // decimal point, then there should be no right digits.
2515 if (ch == digit) {
2516 if (zeroDigitCount > 0) {
2517 ++digitRightCount;
2518 } else {
2519 ++digitLeftCount;
2520 }
2521 if (groupingCount >= 0 && decimalPos < 0) {
2522 ++groupingCount;
2523 }
2524 } else if (ch == zeroDigit) {
2525 if (digitRightCount > 0) {
2526 throw new IllegalArgumentException("Unexpected '0' in pattern \"" +
2527 pattern + '"');
2528 }
2529 ++zeroDigitCount;
2530 if (groupingCount >= 0 && decimalPos < 0) {
2531 ++groupingCount;
2532 }
2533 } else if (ch == groupingSeparator) {
2534 groupingCount = 0;
2535 } else if (ch == decimalSeparator) {
2536 if (decimalPos >= 0) {
2537 throw new IllegalArgumentException("Multiple decimal separators in pattern \"" +
2538 pattern + '"');
2539 }
2540 decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
2541 } else if (pattern.regionMatches(pos, exponent, 0, exponent.length())){
2542 if (useExponentialNotation) {
2543 throw new IllegalArgumentException("Multiple exponential " +
2544 "symbols in pattern \"" + pattern + '"');
2545 }
2546 useExponentialNotation = true;
2547 minExponentDigits = 0;
2548
2549 // Use lookahead to parse out the exponential part
2550 // of the pattern, then jump into phase 2.
2551 pos = pos+exponent.length();
2552 while (pos < pattern.length() &&
2553 pattern.charAt(pos) == zeroDigit) {
2554 ++minExponentDigits;
2555 ++phaseOneLength;
2556 ++pos;
2557 }
2558
2559 if ((digitLeftCount + zeroDigitCount) < 1 ||
2560 minExponentDigits < 1) {
2561 throw new IllegalArgumentException("Malformed exponential " +
2562 "pattern \"" + pattern + '"');
2563 }
2564
2565 // Transition to phase 2
2566 phase = 2;
2567 affix = suffix;
2568 --pos;
2569 continue;
2570 } else {
2571 phase = 2;
2572 affix = suffix;
2573 --pos;
2574 --phaseOneLength;
2575 continue;
2576 }
2577 break;
2578 }
2579 }
2580
2581 // Handle patterns with no '0' pattern character. These patterns
2582 // are legal, but must be interpreted. "##.###" -> "#0.###".
2583 // ".###" -> ".0##".
2584 /* We allow patterns of the form "####" to produce a zeroDigitCount
2585 * of zero (got that?); although this seems like it might make it
2586 * possible for format() to produce empty strings, format() checks
2587 * for this condition and outputs a zero digit in this situation.
2588 * Having a zeroDigitCount of zero yields a minimum integer digits
2589 * of zero, which allows proper round-trip patterns. That is, we
2590 * don't want "#" to become "#0" when toPattern() is called (even
2591 * though that's what it really is, semantically).
2592 */
2593 if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
2594 // Handle "###.###" and "###." and ".###"
2595 int n = decimalPos;
2596 if (n == 0) { // Handle ".###"
2597 ++n;
2598 }
2599 digitRightCount = digitLeftCount - n;
2600 digitLeftCount = n - 1;
2601 zeroDigitCount = 1;
2602 }
2603
2604 // Do syntax checking on the digits.
2605 if ((decimalPos < 0 && digitRightCount > 0) ||
2606 (decimalPos >= 0 && (decimalPos < digitLeftCount ||
2607 decimalPos > (digitLeftCount + zeroDigitCount))) ||
2608 groupingCount == 0 || inQuote) {
2609 throw new IllegalArgumentException("Malformed pattern \"" +
2610 pattern + '"');
2611 }
2612
2613 if (j == 1) {
2614 posPrefixPattern = prefix.toString();
2615 posSuffixPattern = suffix.toString();
2616 negPrefixPattern = posPrefixPattern; // assume these for now
2617 negSuffixPattern = posSuffixPattern;
2618 int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
2619 /* The effectiveDecimalPos is the position the decimal is at or
2620 * would be at if there is no decimal. Note that if decimalPos<0,
2621 * then digitTotalCount == digitLeftCount + zeroDigitCount.
2622 */
2623 int effectiveDecimalPos = decimalPos >= 0 ?
2624 decimalPos : digitTotalCount;
2625 setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
2626 setMaximumIntegerDigits(useExponentialNotation ?
2627 digitLeftCount + getMinimumIntegerDigits() :
2628 MAXIMUM_INTEGER_DIGITS);
2629 setMaximumFractionDigits(decimalPos >= 0 ?
2630 (digitTotalCount - decimalPos) : 0);
2631 setMinimumFractionDigits(decimalPos >= 0 ?
2632 (digitLeftCount + zeroDigitCount - decimalPos) : 0);
2633 setGroupingUsed(groupingCount > 0);
2634 this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
2635 this.multiplier = multiplier;
2636 setDecimalSeparatorAlwaysShown(decimalPos == 0 ||
2637 decimalPos == digitTotalCount);
2638 } else {
2639 negPrefixPattern = prefix.toString();
2640 negSuffixPattern = suffix.toString();
2641 gotNegative = true;
2642 }
2643 }
2644
2645 if (pattern.length() == 0) {
2646 posPrefixPattern = posSuffixPattern = "";
2647 setMinimumIntegerDigits(0);
2648 setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
2649 setMinimumFractionDigits(0);
2650 setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
2651 }
2652
2653 // If there was no negative pattern, or if the negative pattern is
2654 // identical to the positive pattern, then prepend the minus sign to
2655 // the positive pattern to form the negative pattern.
2656 if (!gotNegative ||
2657 (negPrefixPattern.equals(posPrefixPattern)
2658 && negSuffixPattern.equals(posSuffixPattern))) {
2659 negSuffixPattern = posSuffixPattern;
2660 negPrefixPattern = "'-" + posPrefixPattern;
2661 }
2662
2663 expandAffixes();
2664 }
2665
2666 /**
2667 * Sets the maximum number of digits allowed in the integer portion of a
2668 * number.
2669 * For formatting numbers other than <code>BigInteger</code> and
2670 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2671 * 309 is used. Negative input values are replaced with 0.
2672 * @see NumberFormat#setMaximumIntegerDigits
2673 */
2674 public void setMaximumIntegerDigits(int newValue) {
2675 maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2676 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2677 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2678 if (minimumIntegerDigits > maximumIntegerDigits) {
2679 minimumIntegerDigits = maximumIntegerDigits;
2680 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2681 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2682 }
2683 }
2684
2685 /**
2686 * Sets the minimum number of digits allowed in the integer portion of a
2687 * number.
2688 * For formatting numbers other than <code>BigInteger</code> and
2689 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2690 * 309 is used. Negative input values are replaced with 0.
2691 * @see NumberFormat#setMinimumIntegerDigits
2692 */
2693 public void setMinimumIntegerDigits(int newValue) {
2694 minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
2695 super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2696 DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
2697 if (minimumIntegerDigits > maximumIntegerDigits) {
2698 maximumIntegerDigits = minimumIntegerDigits;
2699 super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
2700 DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
2701 }
2702 }
2703
2704 /**
2705 * Sets the maximum number of digits allowed in the fraction portion of a
2706 * number.
2707 * For formatting numbers other than <code>BigInteger</code> and
2708 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2709 * 340 is used. Negative input values are replaced with 0.
2710 * @see NumberFormat#setMaximumFractionDigits
2711 */
2712 public void setMaximumFractionDigits(int newValue) {
2713 maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2714 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2715 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2716 if (minimumFractionDigits > maximumFractionDigits) {
2717 minimumFractionDigits = maximumFractionDigits;
2718 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2719 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2720 }
2721 }
2722
2723 /**
2724 * Sets the minimum number of digits allowed in the fraction portion of a
2725 * number.
2726 * For formatting numbers other than <code>BigInteger</code> and
2727 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2728 * 340 is used. Negative input values are replaced with 0.
2729 * @see NumberFormat#setMinimumFractionDigits
2730 */
2731 public void setMinimumFractionDigits(int newValue) {
2732 minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
2733 super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2734 DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
2735 if (minimumFractionDigits > maximumFractionDigits) {
2736 maximumFractionDigits = minimumFractionDigits;
2737 super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
2738 DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
2739 }
2740 }
2741
2742 /**
2743 * Gets the maximum number of digits allowed in the integer portion of a
2744 * number.
2745 * For formatting numbers other than <code>BigInteger</code> and
2746 * <code>BigDecimal</code> objects, the lower of the return value and
2747 * 309 is used.
2748 * @see #setMaximumIntegerDigits
2749 */
2750 public int getMaximumIntegerDigits() {
2751 return maximumIntegerDigits;
2752 }
2753
2754 /**
2755 * Gets the minimum number of digits allowed in the integer portion of a
2756 * number.
2757 * For formatting numbers other than <code>BigInteger</code> and
2758 * <code>BigDecimal</code> objects, the lower of the return value and
2759 * 309 is used.
2760 * @see #setMinimumIntegerDigits
2761 */
2762 public int getMinimumIntegerDigits() {
2763 return minimumIntegerDigits;
2764 }
2765
2766 /**
2767 * Gets the maximum number of digits allowed in the fraction portion of a
2768 * number.
2769 * For formatting numbers other than <code>BigInteger</code> and
2770 * <code>BigDecimal</code> objects, the lower of the return value and
2771 * 340 is used.
2772 * @see #setMaximumFractionDigits
2773 */
2774 public int getMaximumFractionDigits() {
2775 return maximumFractionDigits;
2776 }
2777
2778 /**
2779 * Gets the minimum number of digits allowed in the fraction portion of a
2780 * number.
2781 * For formatting numbers other than <code>BigInteger</code> and
2782 * <code>BigDecimal</code> objects, the lower of the return value and
2783 * 340 is used.
2784 * @see #setMinimumFractionDigits
2785 */
2786 public int getMinimumFractionDigits() {
2787 return minimumFractionDigits;
2788 }
2789
2790 /**
2791 * Gets the currency used by this decimal format when formatting
2792 * currency values.
2793 * The currency is obtained by calling
2794 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2795 * on this number format's symbols.
2796 *
2797 * @return the currency used by this decimal format, or <code>null</code>
2798 * @since 1.4
2799 */
2800 public Currency getCurrency() {
2801 return symbols.getCurrency();
2802 }
2803
2804 /**
2805 * Sets the currency used by this number format when formatting
2806 * currency values. This does not update the minimum or maximum
2807 * number of fraction digits used by the number format.
2808 * The currency is set by calling
2809 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2810 * on this number format's symbols.
2811 *
2812 * @param currency the new currency to be used by this decimal format
2813 * @exception NullPointerException if <code>currency</code> is null
2814 * @since 1.4
2815 */
2816 public void setCurrency(Currency currency) {
2817 if (currency != symbols.getCurrency()) {
2818 symbols.setCurrency(currency);
2819 if (isCurrencyFormat) {
2820 expandAffixes();
2821 }
2822 }
2823 }
2824
2825 /**
2826 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
2827 *
2828 * @return The <code>RoundingMode</code> used for this DecimalFormat.
2829 * @see #setRoundingMode(RoundingMode)
2830 * @since 1.6
2831 */
2832 public RoundingMode getRoundingMode() {
2833 return roundingMode;
2834 }
2835
2836 /**
2837 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
2838 *
2839 * @param roundingMode The <code>RoundingMode</code> to be used
2840 * @see #getRoundingMode()
2841 * @exception NullPointerException if <code>roundingMode</code> is null.
2842 * @since 1.6
2843 */
2844 public void setRoundingMode(RoundingMode roundingMode) {
2845 if (roundingMode == null) {
2846 throw new NullPointerException();
2847 }
2848
2849 this.roundingMode = roundingMode;
2850 digitList.setRoundingMode(roundingMode);
2851 }
2852
2853 /**
2854 * Adjusts the minimum and maximum fraction digits to values that
2855 * are reasonable for the currency's default fraction digits.
2856 */
2857 void adjustForCurrencyDefaultFractionDigits() {
2858 Currency currency = symbols.getCurrency();
2859 if (currency == null) {
2860 try {
2861 currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
2862 } catch (IllegalArgumentException e) {
2863 }
2864 }
2865 if (currency != null) {
2866 int digits = currency.getDefaultFractionDigits();
2867 if (digits != -1) {
2868 int oldMinDigits = getMinimumFractionDigits();
2869 // Common patterns are "#.##", "#.00", "#".
2870 // Try to adjust all of them in a reasonable way.
2871 if (oldMinDigits == getMaximumFractionDigits()) {
2872 setMinimumFractionDigits(digits);
2873 setMaximumFractionDigits(digits);
2874 } else {
2875 setMinimumFractionDigits(Math.min(digits, oldMinDigits));
2876 setMaximumFractionDigits(digits);
2877 }
2878 }
2879 }
2880 }
2881
2882 /**
2883 * Reads the default serializable fields from the stream and performs
2884 * validations and adjustments for older serialized versions. The
2885 * validations and adjustments are:
2886 * <ol>
2887 * <li>
2888 * Verify that the superclass's digit count fields correctly reflect
2889 * the limits imposed on formatting numbers other than
2890 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2891 * limits are stored in the superclass for serialization compatibility
2892 * with older versions, while the limits for <code>BigInteger</code> and
2893 * <code>BigDecimal</code> objects are kept in this class.
2894 * If, in the superclass, the minimum or maximum integer digit count is
2895 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2896 * maximum fraction digit count is larger than
2897 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2898 * and this method throws an <code>InvalidObjectException</code>.
2899 * <li>
2900 * If <code>serialVersionOnStream</code> is less than 4, initialize
2901 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
2902 * RoundingMode.HALF_EVEN}. This field is new with version 4.
2903 * <li>
2904 * If <code>serialVersionOnStream</code> is less than 3, then call
2905 * the setters for the minimum and maximum integer and fraction digits with
2906 * the values of the corresponding superclass getters to initialize the
2907 * fields in this class. The fields in this class are new with version 3.
2908 * <li>
2909 * If <code>serialVersionOnStream</code> is less than 1, indicating that
2910 * the stream was written by JDK 1.1, initialize
2911 * <code>useExponentialNotation</code>
2912 * to false, since it was not present in JDK 1.1.
2913 * <li>
2914 * Set <code>serialVersionOnStream</code> to the maximum allowed value so
2915 * that default serialization will work properly if this object is streamed
2916 * out again.
2917 * </ol>
2918 *
2919 * <p>Stream versions older than 2 will not have the affix pattern variables
2920 * <code>posPrefixPattern</code> etc. As a result, they will be initialized
2921 * to <code>null</code>, which means the affix strings will be taken as
2922 * literal values. This is exactly what we want, since that corresponds to
2923 * the pre-version-2 behavior.
2924 */
2925 private void readObject(ObjectInputStream stream)
2926 throws IOException, ClassNotFoundException
2927 {
2928 stream.defaultReadObject();
2929 digitList = new DigitList();
2930
2931 if (serialVersionOnStream < 4) {
2932 setRoundingMode(RoundingMode.HALF_EVEN);
2933 }
2934 // We only need to check the maximum counts because NumberFormat
2935 // .readObject has already ensured that the maximum is greater than the
2936 // minimum count.
2937 if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
2938 super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
2939 throw new InvalidObjectException("Digit count out of range");
2940 }
2941 if (serialVersionOnStream < 3) {
2942 setMaximumIntegerDigits(super.getMaximumIntegerDigits());
2943 setMinimumIntegerDigits(super.getMinimumIntegerDigits());
2944 setMaximumFractionDigits(super.getMaximumFractionDigits());
2945 setMinimumFractionDigits(super.getMinimumFractionDigits());
2946 }
2947 if (serialVersionOnStream < 1) {
2948 // Didn't have exponential fields
2949 useExponentialNotation = false;
2950 }
2951 serialVersionOnStream = currentSerialVersion;
2952 }
2953
2954 //----------------------------------------------------------------------
2955 // INSTANCE VARIABLES
2956 //----------------------------------------------------------------------
2957
2958 private transient DigitList digitList = new DigitList();
2959
2960 /**
2961 * The symbol used as a prefix when formatting positive numbers, e.g. "+".
2962 *
2963 * @serial
2964 * @see #getPositivePrefix
2965 */
2966 private String positivePrefix = "";
2967
2968 /**
2969 * The symbol used as a suffix when formatting positive numbers.
2970 * This is often an empty string.
2971 *
2972 * @serial
2973 * @see #getPositiveSuffix
2974 */
2975 private String positiveSuffix = "";
2976
2977 /**
2978 * The symbol used as a prefix when formatting negative numbers, e.g. "-".
2979 *
2980 * @serial
2981 * @see #getNegativePrefix
2982 */
2983 private String negativePrefix = "-";
2984
2985 /**
2986 * The symbol used as a suffix when formatting negative numbers.
2987 * This is often an empty string.
2988 *
2989 * @serial
2990 * @see #getNegativeSuffix
2991 */
2992 private String negativeSuffix = "";
2993
2994 /**
2995 * The prefix pattern for non-negative numbers. This variable corresponds
2996 * to <code>positivePrefix</code>.
2997 *
2998 * <p>This pattern is expanded by the method <code>expandAffix()</code> to
2999 * <code>positivePrefix</code> to update the latter to reflect changes in
3000 * <code>symbols</code>. If this variable is <code>null</code> then
3001 * <code>positivePrefix</code> is taken as a literal value that does not
3002 * change when <code>symbols</code> changes. This variable is always
3003 * <code>null</code> for <code>DecimalFormat</code> objects older than
3004 * stream version 2 restored from stream.
3005 *
3006 * @serial
3007 * @since 1.3
3008 */
3009 private String posPrefixPattern;
3010
3011 /**
3012 * The suffix pattern for non-negative numbers. This variable corresponds
3013 * to <code>positiveSuffix</code>. This variable is analogous to
3014 * <code>posPrefixPattern</code>; see that variable for further
3015 * documentation.
3016 *
3017 * @serial
3018 * @since 1.3
3019 */
3020 private String posSuffixPattern;
3021
3022 /**
3023 * The prefix pattern for negative numbers. This variable corresponds
3024 * to <code>negativePrefix</code>. This variable is analogous to
3025 * <code>posPrefixPattern</code>; see that variable for further
3026 * documentation.
3027 *
3028 * @serial
3029 * @since 1.3
3030 */
3031 private String negPrefixPattern;
3032
3033 /**
3034 * The suffix pattern for negative numbers. This variable corresponds
3035 * to <code>negativeSuffix</code>. This variable is analogous to
3036 * <code>posPrefixPattern</code>; see that variable for further
3037 * documentation.
3038 *
3039 * @serial
3040 * @since 1.3
3041 */
3042 private String negSuffixPattern;
3043
3044 /**
3045 * The multiplier for use in percent, per mille, etc.
3046 *
3047 * @serial
3048 * @see #getMultiplier
3049 */
3050 private int multiplier = 1;
3051
3052 /**
3053 * The number of digits between grouping separators in the integer
3054 * portion of a number. Must be greater than 0 if
3055 * <code>NumberFormat.groupingUsed</code> is true.
3056 *
3057 * @serial
3058 * @see #getGroupingSize
3059 * @see java.text.NumberFormat#isGroupingUsed
3060 */
3061 private byte groupingSize = 3; // invariant, > 0 if useThousands
3062
3063 /**
3064 * If true, forces the decimal separator to always appear in a formatted
3065 * number, even if the fractional part of the number is zero.
3066 *
3067 * @serial
3068 * @see #isDecimalSeparatorAlwaysShown
3069 */
3070 private boolean decimalSeparatorAlwaysShown = false;
3071
3072 /**
3073 * If true, parse returns BigDecimal wherever possible.
3074 *
3075 * @serial
3076 * @see #isParseBigDecimal
3077 * @since 1.5
3078 */
3079 private boolean parseBigDecimal = false;
3080
3081
3082 /**
3083 * True if this object represents a currency format. This determines
3084 * whether the monetary decimal separator is used instead of the normal one.
3085 */
3086 private transient boolean isCurrencyFormat = false;
3087
3088 /**
3089 * The <code>DecimalFormatSymbols</code> object used by this format.
3090 * It contains the symbols used to format numbers, e.g. the grouping separator,
3091 * decimal separator, and so on.
3092 *
3093 * @serial
3094 * @see #setDecimalFormatSymbols
3095 * @see java.text.DecimalFormatSymbols
3096 */
3097 private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
3098
3099 /**
3100 * True to force the use of exponential (i.e. scientific) notation when formatting
3101 * numbers.
3102 *
3103 * @serial
3104 * @since 1.2
3105 */
3106 private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.2
3107
3108 /**
3109 * FieldPositions describing the positive prefix String. This is
3110 * lazily created. Use <code>getPositivePrefixFieldPositions</code>
3111 * when needed.
3112 */
3113 private transient FieldPosition[] positivePrefixFieldPositions;
3114
3115 /**
3116 * FieldPositions describing the positive suffix String. This is
3117 * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
3118 * when needed.
3119 */
3120 private transient FieldPosition[] positiveSuffixFieldPositions;
3121
3122 /**
3123 * FieldPositions describing the negative prefix String. This is
3124 * lazily created. Use <code>getNegativePrefixFieldPositions</code>
3125 * when needed.
3126 */
3127 private transient FieldPosition[] negativePrefixFieldPositions;
3128
3129 /**
3130 * FieldPositions describing the negative suffix String. This is
3131 * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
3132 * when needed.
3133 */
3134 private transient FieldPosition[] negativeSuffixFieldPositions;
3135
3136 /**
3137 * The minimum number of digits used to display the exponent when a number is
3138 * formatted in exponential notation. This field is ignored if
3139 * <code>useExponentialNotation</code> is not true.
3140 *
3141 * @serial
3142 * @since 1.2
3143 */
3144 private byte minExponentDigits; // Newly persistent in the Java 2 platform v.1.2
3145
3146 /**
3147 * The maximum number of digits allowed in the integer portion of a
3148 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3149 * <code>maximumIntegerDigits</code> must be greater than or equal to
3150 * <code>minimumIntegerDigits</code>.
3151 *
3152 * @serial
3153 * @see #getMaximumIntegerDigits
3154 * @since 1.5
3155 */
3156 private int maximumIntegerDigits = super.getMaximumIntegerDigits();
3157
3158 /**
3159 * The minimum number of digits allowed in the integer portion of a
3160 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3161 * <code>minimumIntegerDigits</code> must be less than or equal to
3162 * <code>maximumIntegerDigits</code>.
3163 *
3164 * @serial
3165 * @see #getMinimumIntegerDigits
3166 * @since 1.5
3167 */
3168 private int minimumIntegerDigits = super.getMinimumIntegerDigits();
3169
3170 /**
3171 * The maximum number of digits allowed in the fractional portion of a
3172 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3173 * <code>maximumFractionDigits</code> must be greater than or equal to
3174 * <code>minimumFractionDigits</code>.
3175 *
3176 * @serial
3177 * @see #getMaximumFractionDigits
3178 * @since 1.5
3179 */
3180 private int maximumFractionDigits = super.getMaximumFractionDigits();
3181
3182 /**
3183 * The minimum number of digits allowed in the fractional portion of a
3184 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3185 * <code>minimumFractionDigits</code> must be less than or equal to
3186 * <code>maximumFractionDigits</code>.
3187 *
3188 * @serial
3189 * @see #getMinimumFractionDigits
3190 * @since 1.5
3191 */
3192 private int minimumFractionDigits = super.getMinimumFractionDigits();
3193
3194 /**
3195 * The {@link java.math.RoundingMode} used in this DecimalFormat.
3196 *
3197 * @serial
3198 * @since 1.6
3199 */
3200 private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
3201
3202 //----------------------------------------------------------------------
3203
3204 static final int currentSerialVersion = 4;
3205
3206 /**
3207 * The internal serial version which says which version was written.
3208 * Possible values are:
3209 * <ul>
3210 * <li><b>0</b> (default): versions before the Java 2 platform v1.2
3211 * <li><b>1</b>: version for 1.2, which includes the two new fields
3212 * <code>useExponentialNotation</code> and
3213 * <code>minExponentDigits</code>.
3214 * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
3215 * <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
3216 * <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
3217 * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
3218 * <code>maximumIntegerDigits</code>,
3219 * <code>minimumIntegerDigits</code>,
3220 * <code>maximumFractionDigits</code>,
3221 * <code>minimumFractionDigits</code>, and
3222 * <code>parseBigDecimal</code>.
3223 * <li><b>4</b>: version for 1.6 and later, which adds one new field:
3224 * <code>roundingMode</code>.
3225 * </ul>
3226 * @since 1.2
3227 * @serial
3228 */
3229 private int serialVersionOnStream = currentSerialVersion;
3230
3231 //----------------------------------------------------------------------
3232 // CONSTANTS
3233 //----------------------------------------------------------------------
3234
3235 // Constants for characters used in programmatic (unlocalized) patterns.
3236 private static final char PATTERN_ZERO_DIGIT = '0';
3237 private static final char PATTERN_GROUPING_SEPARATOR = ',';
3238 private static final char PATTERN_DECIMAL_SEPARATOR = '.';
3239 private static final char PATTERN_PER_MILLE = '\u2030';
3240 private static final char PATTERN_PERCENT = '%';
3241 private static final char PATTERN_DIGIT = '#';
3242 private static final char PATTERN_SEPARATOR = ';';
3243 private static final String PATTERN_EXPONENT = "E";
3244 private static final char PATTERN_MINUS = '-';
3245
3246 /**
3247 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
3248 * is used in patterns and substituted with either the currency symbol,
3249 * or if it is doubled, with the international currency symbol. If the
3250 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
3251 * replaced with the monetary decimal separator.
3252 *
3253 * The CURRENCY_SIGN is not localized.
3254 */
3255 private static final char CURRENCY_SIGN = '\u00A4';
3256
3257 private static final char QUOTE = '\'';
3258
3259 private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
3260
3261 // Upper limit on integer and fraction digits for a Java double
3262 static final int DOUBLE_INTEGER_DIGITS = 309;
3263 static final int DOUBLE_FRACTION_DIGITS = 340;
3264
3265 // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3266 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;
3267 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3268
3269 // Proclaim JDK 1.1 serial compatibility.
3270 static final long serialVersionUID = 864413376551465018L;
3271
3272 /**
3273 * Cache to hold the NumberPattern of a Locale.
3274 */
3275 private static Hashtable cachedLocaleData = new Hashtable(3);
3276}