History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/text/DecimalFormat.java (1 of 18352 files). Show all

Unified · Split

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