0001 /*
0002 * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 /*
0027 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
0028 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
0029 *
0030 * The original version of this source code and documentation is copyrighted
0031 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
0032 * materials are provided under terms of a License Agreement between Taligent
0033 * and Sun. This technology is protected by multiple US and International
0034 * patents. This notice and attribution to Taligent may not be removed.
0035 * Taligent is a registered trademark of Taligent, Inc.
0036 *
0037 */
0038
0039 package java.text;
0040
0041 import java.io.InvalidObjectException;
0042 import java.io.IOException;
0043 import java.io.ObjectInputStream;
0044 import java.math.BigDecimal;
0045 import java.math.BigInteger;
0046 import java.math.RoundingMode;
0047 import java.util.ArrayList;
0048 import java.util.Currency;
0049 import java.util.Hashtable;
0050 import java.util.Locale;
0051 import java.util.ResourceBundle;
0052 import java.util.concurrent.atomic.AtomicInteger;
0053 import java.util.concurrent.atomic.AtomicLong;
0054 import sun.util.resources.LocaleData;
0055
0056 /**
0057 * <code>DecimalFormat</code> is a concrete subclass of
0058 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
0059 * features designed to make it possible to parse and format numbers in any
0060 * locale, including support for Western, Arabic, and Indic digits. It also
0061 * supports different kinds of numbers, including integers (123), fixed-point
0062 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
0063 * currency amounts ($123). All of these can be localized.
0064 *
0065 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
0066 * default locale, call one of <code>NumberFormat</code>'s factory methods, such
0067 * as <code>getInstance()</code>. In general, do not call the
0068 * <code>DecimalFormat</code> constructors directly, since the
0069 * <code>NumberFormat</code> factory methods may return subclasses other than
0070 * <code>DecimalFormat</code>. If you need to customize the format object, do
0071 * something like this:
0072 *
0073 * <blockquote><pre>
0074 * NumberFormat f = NumberFormat.getInstance(loc);
0075 * if (f instanceof DecimalFormat) {
0076 * ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
0077 * }
0078 * </pre></blockquote>
0079 *
0080 * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
0081 * <em>symbols</em>. The pattern may be set directly using
0082 * <code>applyPattern()</code>, or indirectly using the API methods. The
0083 * symbols are stored in a <code>DecimalFormatSymbols</code> object. When using
0084 * the <code>NumberFormat</code> factory methods, the pattern and symbols are
0085 * read from localized <code>ResourceBundle</code>s.
0086 *
0087 * <h4>Patterns</h4>
0088 *
0089 * <code>DecimalFormat</code> patterns have the following syntax:
0090 * <blockquote><pre>
0091 * <i>Pattern:</i>
0092 * <i>PositivePattern</i>
0093 * <i>PositivePattern</i> ; <i>NegativePattern</i>
0094 * <i>PositivePattern:</i>
0095 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
0096 * <i>NegativePattern:</i>
0097 * <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
0098 * <i>Prefix:</i>
0099 * any Unicode characters except \uFFFE, \uFFFF, and special characters
0100 * <i>Suffix:</i>
0101 * any Unicode characters except \uFFFE, \uFFFF, and special characters
0102 * <i>Number:</i>
0103 * <i>Integer</i> <i>Exponent<sub>opt</sub></i>
0104 * <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
0105 * <i>Integer:</i>
0106 * <i>MinimumInteger</i>
0107 * #
0108 * # <i>Integer</i>
0109 * # , <i>Integer</i>
0110 * <i>MinimumInteger:</i>
0111 * 0
0112 * 0 <i>MinimumInteger</i>
0113 * 0 , <i>MinimumInteger</i>
0114 * <i>Fraction:</i>
0115 * <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
0116 * <i>MinimumFraction:</i>
0117 * 0 <i>MinimumFraction<sub>opt</sub></i>
0118 * <i>OptionalFraction:</i>
0119 * # <i>OptionalFraction<sub>opt</sub></i>
0120 * <i>Exponent:</i>
0121 * E <i>MinimumExponent</i>
0122 * <i>MinimumExponent:</i>
0123 * 0 <i>MinimumExponent<sub>opt</sub></i>
0124 * </pre></blockquote>
0125 *
0126 * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
0127 * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>. Each
0128 * subpattern has a prefix, numeric part, and suffix. The negative subpattern
0129 * is optional; if absent, then the positive subpattern prefixed with the
0130 * localized minus sign (<code>'-'</code> in most locales) is used as the
0131 * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
0132 * <code>"0.00;-0.00"</code>. If there is an explicit negative subpattern, it
0133 * serves only to specify the negative prefix and suffix; the number of digits,
0134 * minimal digits, and other characteristics are all the same as the positive
0135 * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
0136 * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
0137 *
0138 * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
0139 * thousands separators, decimal separators, etc. may be set to arbitrary
0140 * values, and they will appear properly during formatting. However, care must
0141 * be taken that the symbols and strings do not conflict, or parsing will be
0142 * unreliable. For example, either the positive and negative prefixes or the
0143 * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
0144 * to distinguish positive from negative values. (If they are identical, then
0145 * <code>DecimalFormat</code> will behave as if no negative subpattern was
0146 * specified.) Another example is that the decimal separator and thousands
0147 * separator should be distinct characters, or parsing will be impossible.
0148 *
0149 * <p>The grouping separator is commonly used for thousands, but in some
0150 * countries it separates ten-thousands. The grouping size is a constant number
0151 * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
0152 * 1,0000,0000. If you supply a pattern with multiple grouping characters, the
0153 * interval between the last one and the end of the integer is the one that is
0154 * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
0155 * <code>"##,####,####"</code>.
0156 *
0157 * <h4>Special Pattern Characters</h4>
0158 *
0159 * <p>Many characters in a pattern are taken literally; they are matched during
0160 * parsing and output unchanged during formatting. Special characters, on the
0161 * other hand, stand for other characters, strings, or classes of characters.
0162 * They must be quoted, unless noted otherwise, if they are to appear in the
0163 * prefix or suffix as literals.
0164 *
0165 * <p>The characters listed here are used in non-localized patterns. Localized
0166 * patterns use the corresponding characters taken from this formatter's
0167 * <code>DecimalFormatSymbols</code> object instead, and these characters lose
0168 * their special status. Two exceptions are the currency sign and quote, which
0169 * are not localized.
0170 *
0171 * <blockquote>
0172 * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
0173 * location, localized, and meaning.">
0174 * <tr bgcolor="#ccccff">
0175 * <th align=left>Symbol
0176 * <th align=left>Location
0177 * <th align=left>Localized?
0178 * <th align=left>Meaning
0179 * <tr valign=top>
0180 * <td><code>0</code>
0181 * <td>Number
0182 * <td>Yes
0183 * <td>Digit
0184 * <tr valign=top bgcolor="#eeeeff">
0185 * <td><code>#</code>
0186 * <td>Number
0187 * <td>Yes
0188 * <td>Digit, zero shows as absent
0189 * <tr valign=top>
0190 * <td><code>.</code>
0191 * <td>Number
0192 * <td>Yes
0193 * <td>Decimal separator or monetary decimal separator
0194 * <tr valign=top bgcolor="#eeeeff">
0195 * <td><code>-</code>
0196 * <td>Number
0197 * <td>Yes
0198 * <td>Minus sign
0199 * <tr valign=top>
0200 * <td><code>,</code>
0201 * <td>Number
0202 * <td>Yes
0203 * <td>Grouping separator
0204 * <tr valign=top bgcolor="#eeeeff">
0205 * <td><code>E</code>
0206 * <td>Number
0207 * <td>Yes
0208 * <td>Separates mantissa and exponent in scientific notation.
0209 * <em>Need not be quoted in prefix or suffix.</em>
0210 * <tr valign=top>
0211 * <td><code>;</code>
0212 * <td>Subpattern boundary
0213 * <td>Yes
0214 * <td>Separates positive and negative subpatterns
0215 * <tr valign=top bgcolor="#eeeeff">
0216 * <td><code>%</code>
0217 * <td>Prefix or suffix
0218 * <td>Yes
0219 * <td>Multiply by 100 and show as percentage
0220 * <tr valign=top>
0221 * <td><code>\u2030</code>
0222 * <td>Prefix or suffix
0223 * <td>Yes
0224 * <td>Multiply by 1000 and show as per mille value
0225 * <tr valign=top bgcolor="#eeeeff">
0226 * <td><code>¤</code> (<code>\u00A4</code>)
0227 * <td>Prefix or suffix
0228 * <td>No
0229 * <td>Currency sign, replaced by currency symbol. If
0230 * doubled, replaced by international currency symbol.
0231 * If present in a pattern, the monetary decimal separator
0232 * is used instead of the decimal separator.
0233 * <tr valign=top>
0234 * <td><code>'</code>
0235 * <td>Prefix or suffix
0236 * <td>No
0237 * <td>Used to quote special characters in a prefix or suffix,
0238 * for example, <code>"'#'#"</code> formats 123 to
0239 * <code>"#123"</code>. To create a single quote
0240 * itself, use two in a row: <code>"# o''clock"</code>.
0241 * </table>
0242 * </blockquote>
0243 *
0244 * <h4>Scientific Notation</h4>
0245 *
0246 * <p>Numbers in scientific notation are expressed as the product of a mantissa
0247 * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3. The
0248 * mantissa is often in the range 1.0 <= x < 10.0, but it need not be.
0249 * <code>DecimalFormat</code> can be instructed to format and parse scientific
0250 * notation <em>only via a pattern</em>; there is currently no factory method
0251 * that creates a scientific notation format. In a pattern, the exponent
0252 * character immediately followed by one or more digit characters indicates
0253 * scientific notation. Example: <code>"0.###E0"</code> formats the number
0254 * 1234 as <code>"1.234E3"</code>.
0255 *
0256 * <ul>
0257 * <li>The number of digit characters after the exponent character gives the
0258 * minimum exponent digit count. There is no maximum. Negative exponents are
0259 * formatted using the localized minus sign, <em>not</em> the prefix and suffix
0260 * from the pattern. This allows patterns such as <code>"0.###E0 m/s"</code>.
0261 *
0262 * <li>The minimum and maximum number of integer digits are interpreted
0263 * together:
0264 *
0265 * <ul>
0266 * <li>If the maximum number of integer digits is greater than their minimum number
0267 * and greater than 1, it forces the exponent to be a multiple of the maximum
0268 * number of integer digits, and the minimum number of integer digits to be
0269 * interpreted as 1. The most common use of this is to generate
0270 * <em>engineering notation</em>, in which the exponent is a multiple of three,
0271 * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
0272 * formats to <code>"12.345E3"</code>, and 123456 formats to
0273 * <code>"123.456E3"</code>.
0274 *
0275 * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
0276 * exponent. Example: 0.00123 formatted with <code>"00.###E0"</code> yields
0277 * <code>"12.3E-4"</code>.
0278 * </ul>
0279 *
0280 * <li>The number of significant digits in the mantissa is the sum of the
0281 * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
0282 * unaffected by the maximum integer digits. For example, 12345 formatted with
0283 * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
0284 * the significant digits count to zero. The number of significant digits
0285 * does not affect parsing.
0286 *
0287 * <li>Exponential patterns may not contain grouping separators.
0288 * </ul>
0289 *
0290 * <h4>Rounding</h4>
0291 *
0292 * <code>DecimalFormat</code> provides rounding modes defined in
0293 * {@link java.math.RoundingMode} for formatting. By default, it uses
0294 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
0295 *
0296 * <h4>Digits</h4>
0297 *
0298 * For formatting, <code>DecimalFormat</code> uses the ten consecutive
0299 * characters starting with the localized zero digit defined in the
0300 * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
0301 * digits as well as all Unicode decimal digits, as defined by
0302 * {@link Character#digit Character.digit}, are recognized.
0303 *
0304 * <h4>Special Values</h4>
0305 *
0306 * <p><code>NaN</code> is formatted as a string, which typically has a single character
0307 * <code>\uFFFD</code>. This string is determined by the
0308 * <code>DecimalFormatSymbols</code> object. This is the only value for which
0309 * the prefixes and suffixes are not used.
0310 *
0311 * <p>Infinity is formatted as a string, which typically has a single character
0312 * <code>\u221E</code>, with the positive or negative prefixes and suffixes
0313 * applied. The infinity string is determined by the
0314 * <code>DecimalFormatSymbols</code> object.
0315 *
0316 * <p>Negative zero (<code>"-0"</code>) parses to
0317 * <ul>
0318 * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
0319 * true,
0320 * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
0321 * and <code>isParseIntegerOnly()</code> is true,
0322 * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
0323 * and <code>isParseIntegerOnly()</code> are false.
0324 * </ul>
0325 *
0326 * <h4><a name="synchronization">Synchronization</a></h4>
0327 *
0328 * <p>
0329 * Decimal formats are generally not synchronized.
0330 * It is recommended to create separate format instances for each thread.
0331 * If multiple threads access a format concurrently, it must be synchronized
0332 * externally.
0333 *
0334 * <h4>Example</h4>
0335 *
0336 * <blockquote><pre>
0337 * <strong>// Print out a number using the localized number, integer, currency,
0338 * // and percent format for each locale</strong>
0339 * Locale[] locales = NumberFormat.getAvailableLocales();
0340 * double myNumber = -1234.56;
0341 * NumberFormat form;
0342 * for (int j=0; j<4; ++j) {
0343 * System.out.println("FORMAT");
0344 * for (int i = 0; i < locales.length; ++i) {
0345 * if (locales[i].getCountry().length() == 0) {
0346 * continue; // Skip language-only locales
0347 * }
0348 * System.out.print(locales[i].getDisplayName());
0349 * switch (j) {
0350 * case 0:
0351 * form = NumberFormat.getInstance(locales[i]); break;
0352 * case 1:
0353 * form = NumberFormat.getIntegerInstance(locales[i]); break;
0354 * case 2:
0355 * form = NumberFormat.getCurrencyInstance(locales[i]); break;
0356 * default:
0357 * form = NumberFormat.getPercentInstance(locales[i]); break;
0358 * }
0359 * if (form instanceof DecimalFormat) {
0360 * System.out.print(": " + ((DecimalFormat) form).toPattern());
0361 * }
0362 * System.out.print(" -> " + form.format(myNumber));
0363 * try {
0364 * System.out.println(" -> " + form.parse(form.format(myNumber)));
0365 * } catch (ParseException e) {}
0366 * }
0367 * }
0368 * </pre></blockquote>
0369 *
0370 * @see <a href="http://java.sun.com/docs/books/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
0371 * @see NumberFormat
0372 * @see DecimalFormatSymbols
0373 * @see ParsePosition
0374 * @version 1.94 05/05/07
0375 * @author Mark Davis
0376 * @author Alan Liu
0377 */
0378 public class DecimalFormat extends NumberFormat {
0379
0380 /**
0381 * Creates a DecimalFormat using the default pattern and symbols
0382 * for the default locale. This is a convenient way to obtain a
0383 * DecimalFormat when internationalization is not the main concern.
0384 * <p>
0385 * To obtain standard formats for a given locale, use the factory methods
0386 * on NumberFormat such as getNumberInstance. These factories will
0387 * return the most appropriate sub-class of NumberFormat for a given
0388 * locale.
0389 *
0390 * @see java.text.NumberFormat#getInstance
0391 * @see java.text.NumberFormat#getNumberInstance
0392 * @see java.text.NumberFormat#getCurrencyInstance
0393 * @see java.text.NumberFormat#getPercentInstance
0394 */
0395 public DecimalFormat() {
0396 Locale def = Locale.getDefault();
0397 // try to get the pattern from the cache
0398 String pattern = (String) cachedLocaleData.get(def);
0399 if (pattern == null) { /* cache miss */
0400 // Get the pattern for the default locale.
0401 ResourceBundle rb = LocaleData.getNumberFormatData(def);
0402 String[] all = rb.getStringArray("NumberPatterns");
0403 pattern = all[0];
0404 /* update cache */
0405 cachedLocaleData.put(def, pattern);
0406 }
0407
0408 // Always applyPattern after the symbols are set
0409 this .symbols = new DecimalFormatSymbols(def);
0410 applyPattern(pattern, false);
0411 }
0412
0413 /**
0414 * Creates a DecimalFormat using the given pattern and the symbols
0415 * for the default locale. This is a convenient way to obtain a
0416 * DecimalFormat when internationalization is not the main concern.
0417 * <p>
0418 * To obtain standard formats for a given locale, use the factory methods
0419 * on NumberFormat such as getNumberInstance. These factories will
0420 * return the most appropriate sub-class of NumberFormat for a given
0421 * locale.
0422 *
0423 * @param pattern A non-localized pattern string.
0424 * @exception NullPointerException if <code>pattern</code> is null
0425 * @exception IllegalArgumentException if the given pattern is invalid.
0426 * @see java.text.NumberFormat#getInstance
0427 * @see java.text.NumberFormat#getNumberInstance
0428 * @see java.text.NumberFormat#getCurrencyInstance
0429 * @see java.text.NumberFormat#getPercentInstance
0430 */
0431 public DecimalFormat(String pattern) {
0432 // Always applyPattern after the symbols are set
0433 this .symbols = new DecimalFormatSymbols(Locale.getDefault());
0434 applyPattern(pattern, false);
0435 }
0436
0437 /**
0438 * Creates a DecimalFormat using the given pattern and symbols.
0439 * Use this constructor when you need to completely customize the
0440 * behavior of the format.
0441 * <p>
0442 * To obtain standard formats for a given
0443 * locale, use the factory methods on NumberFormat such as
0444 * getInstance or getCurrencyInstance. If you need only minor adjustments
0445 * to a standard format, you can modify the format returned by
0446 * a NumberFormat factory method.
0447 *
0448 * @param pattern a non-localized pattern string
0449 * @param symbols the set of symbols to be used
0450 * @exception NullPointerException if any of the given arguments is null
0451 * @exception IllegalArgumentException if the given pattern is invalid
0452 * @see java.text.NumberFormat#getInstance
0453 * @see java.text.NumberFormat#getNumberInstance
0454 * @see java.text.NumberFormat#getCurrencyInstance
0455 * @see java.text.NumberFormat#getPercentInstance
0456 * @see java.text.DecimalFormatSymbols
0457 */
0458 public DecimalFormat(String pattern, DecimalFormatSymbols symbols) {
0459 // Always applyPattern after the symbols are set
0460 this .symbols = (DecimalFormatSymbols) symbols.clone();
0461 applyPattern(pattern, false);
0462 }
0463
0464 // Overrides
0465 /**
0466 * Formats a number and appends the resulting text to the given string
0467 * buffer.
0468 * The number can be of any subclass of {@link java.lang.Number}.
0469 * <p>
0470 * This implementation uses the maximum precision permitted.
0471 * @param number the number to format
0472 * @param toAppendTo the <code>StringBuffer</code> to which the formatted
0473 * text is to be appended
0474 * @param pos On input: an alignment field, if desired.
0475 * On output: the offsets of the alignment field.
0476 * @return the value passed in as <code>toAppendTo</code>
0477 * @exception IllegalArgumentException if <code>number</code> is
0478 * null or not an instance of <code>Number</code>.
0479 * @exception NullPointerException if <code>toAppendTo</code> or
0480 * <code>pos</code> is null
0481 * @exception ArithmeticException if rounding is needed with rounding
0482 * mode being set to RoundingMode.UNNECESSARY
0483 * @see java.text.FieldPosition
0484 */
0485 public final StringBuffer format(Object number,
0486 StringBuffer toAppendTo, FieldPosition pos) {
0487 if (number instanceof Long
0488 || number instanceof Integer
0489 || number instanceof Short
0490 || number instanceof Byte
0491 || number instanceof AtomicInteger
0492 || number instanceof AtomicLong
0493 || (number instanceof BigInteger && ((BigInteger) number)
0494 .bitLength() < 64)) {
0495 return format(((Number) number).longValue(), toAppendTo,
0496 pos);
0497 } else if (number instanceof BigDecimal) {
0498 return format((BigDecimal) number, toAppendTo, pos);
0499 } else if (number instanceof BigInteger) {
0500 return format((BigInteger) number, toAppendTo, pos);
0501 } else if (number instanceof Number) {
0502 return format(((Number) number).doubleValue(), toAppendTo,
0503 pos);
0504 } else {
0505 throw new IllegalArgumentException(
0506 "Cannot format given Object as a Number");
0507 }
0508 }
0509
0510 /**
0511 * Formats a double to produce a string.
0512 * @param number The double to format
0513 * @param result where the text is to be appended
0514 * @param fieldPosition On input: an alignment field, if desired.
0515 * On output: the offsets of the alignment field.
0516 * @exception ArithmeticException if rounding is needed with rounding
0517 * mode being set to RoundingMode.UNNECESSARY
0518 * @return The formatted number string
0519 * @see java.text.FieldPosition
0520 */
0521 public StringBuffer format(double number, StringBuffer result,
0522 FieldPosition fieldPosition) {
0523 fieldPosition.setBeginIndex(0);
0524 fieldPosition.setEndIndex(0);
0525
0526 return format(number, result, fieldPosition.getFieldDelegate());
0527 }
0528
0529 /**
0530 * Formats a double to produce a string.
0531 * @param number The double to format
0532 * @param result where the text is to be appended
0533 * @param delegate notified of locations of sub fields
0534 * @exception ArithmeticException if rounding is needed with rounding
0535 * mode being set to RoundingMode.UNNECESSARY
0536 * @return The formatted number string
0537 */
0538 private StringBuffer format(double number, StringBuffer result,
0539 FieldDelegate delegate) {
0540 if (Double.isNaN(number)
0541 || (Double.isInfinite(number) && multiplier == 0)) {
0542 int iFieldStart = result.length();
0543 result.append(symbols.getNaN());
0544 delegate
0545 .formatted(INTEGER_FIELD, Field.INTEGER,
0546 Field.INTEGER, iFieldStart,
0547 result.length(), result);
0548 return result;
0549 }
0550
0551 /* Detecting whether a double is negative is easy with the exception of
0552 * the value -0.0. This is a double which has a zero mantissa (and
0553 * exponent), but a negative sign bit. It is semantically distinct from
0554 * a zero with a positive sign bit, and this distinction is important
0555 * to certain kinds of computations. However, it's a little tricky to
0556 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may
0557 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==
0558 * -Infinity. Proper detection of -0.0 is needed to deal with the
0559 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
0560 */
0561 boolean isNegative = ((number < 0.0) || (number == 0.0 && 1 / number < 0.0))
0562 ^ (multiplier < 0);
0563
0564 if (multiplier != 1) {
0565 number *= multiplier;
0566 }
0567
0568 if (Double.isInfinite(number)) {
0569 if (isNegative) {
0570 append(result, negativePrefix, delegate,
0571 getNegativePrefixFieldPositions(), Field.SIGN);
0572 } else {
0573 append(result, positivePrefix, delegate,
0574 getPositivePrefixFieldPositions(), Field.SIGN);
0575 }
0576
0577 int iFieldStart = result.length();
0578 result.append(symbols.getInfinity());
0579 delegate
0580 .formatted(INTEGER_FIELD, Field.INTEGER,
0581 Field.INTEGER, iFieldStart,
0582 result.length(), result);
0583
0584 if (isNegative) {
0585 append(result, negativeSuffix, delegate,
0586 getNegativeSuffixFieldPositions(), Field.SIGN);
0587 } else {
0588 append(result, positiveSuffix, delegate,
0589 getPositiveSuffixFieldPositions(), Field.SIGN);
0590 }
0591
0592 return result;
0593 }
0594
0595 if (isNegative) {
0596 number = -number;
0597 }
0598
0599 // at this point we are guaranteed a nonnegative finite number.
0600 assert (number >= 0 && !Double.isInfinite(number));
0601
0602 synchronized (digitList) {
0603 int maxIntDigits = super .getMaximumIntegerDigits();
0604 int minIntDigits = super .getMinimumIntegerDigits();
0605 int maxFraDigits = super .getMaximumFractionDigits();
0606 int minFraDigits = super .getMinimumFractionDigits();
0607
0608 digitList.set(isNegative, number,
0609 useExponentialNotation ? maxIntDigits
0610 + maxFraDigits : maxFraDigits,
0611 !useExponentialNotation);
0612 return subformat(result, delegate, isNegative, false,
0613 maxIntDigits, minIntDigits, maxFraDigits,
0614 minFraDigits);
0615 }
0616 }
0617
0618 /**
0619 * Format a long to produce a string.
0620 * @param number The long to format
0621 * @param result where the text is to be appended
0622 * @param fieldPosition On input: an alignment field, if desired.
0623 * On output: the offsets of the alignment field.
0624 * @exception ArithmeticException if rounding is needed with rounding
0625 * mode being set to RoundingMode.UNNECESSARY
0626 * @return The formatted number string
0627 * @see java.text.FieldPosition
0628 */
0629 public StringBuffer format(long number, StringBuffer result,
0630 FieldPosition fieldPosition) {
0631 fieldPosition.setBeginIndex(0);
0632 fieldPosition.setEndIndex(0);
0633
0634 return format(number, result, fieldPosition.getFieldDelegate());
0635 }
0636
0637 /**
0638 * Format a long to produce a string.
0639 * @param number The long to format
0640 * @param result where the text is to be appended
0641 * @param delegate notified of locations of sub fields
0642 * @return The formatted number string
0643 * @exception ArithmeticException if rounding is needed with rounding
0644 * mode being set to RoundingMode.UNNECESSARY
0645 * @see java.text.FieldPosition
0646 */
0647 private StringBuffer format(long number, StringBuffer result,
0648 FieldDelegate delegate) {
0649 boolean isNegative = (number < 0);
0650 if (isNegative) {
0651 number = -number;
0652 }
0653
0654 // In general, long values always represent real finite numbers, so
0655 // we don't have to check for +/- Infinity or NaN. However, there
0656 // is one case we have to be careful of: The multiplier can push
0657 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We
0658 // check for this before multiplying, and if it happens we use
0659 // BigInteger instead.
0660 boolean useBigInteger = false;
0661 if (number < 0) { // This can only happen if number == Long.MIN_VALUE.
0662 if (multiplier != 0) {
0663 useBigInteger = true;
0664 }
0665 } else if (multiplier != 1 && multiplier != 0) {
0666 long cutoff = Long.MAX_VALUE / multiplier;
0667 if (cutoff < 0) {
0668 cutoff = -cutoff;
0669 }
0670 useBigInteger = (number > cutoff);
0671 }
0672
0673 if (useBigInteger) {
0674 if (isNegative) {
0675 number = -number;
0676 }
0677 BigInteger bigIntegerValue = BigInteger.valueOf(number);
0678 return format(bigIntegerValue, result, delegate, true);
0679 }
0680
0681 number *= multiplier;
0682 if (number == 0) {
0683 isNegative = false;
0684 } else {
0685 if (multiplier < 0) {
0686 number = -number;
0687 isNegative = !isNegative;
0688 }
0689 }
0690
0691 synchronized (digitList) {
0692 int maxIntDigits = super .getMaximumIntegerDigits();
0693 int minIntDigits = super .getMinimumIntegerDigits();
0694 int maxFraDigits = super .getMaximumFractionDigits();
0695 int minFraDigits = super .getMinimumFractionDigits();
0696
0697 digitList.set(isNegative, number,
0698 useExponentialNotation ? maxIntDigits
0699 + maxFraDigits : 0);
0700
0701 return subformat(result, delegate, isNegative, true,
0702 maxIntDigits, minIntDigits, maxFraDigits,
0703 minFraDigits);
0704 }
0705 }
0706
0707 /**
0708 * Formats a BigDecimal to produce a string.
0709 * @param number The BigDecimal to format
0710 * @param result where the text is to be appended
0711 * @param fieldPosition On input: an alignment field, if desired.
0712 * On output: the offsets of the alignment field.
0713 * @return The formatted number string
0714 * @exception ArithmeticException if rounding is needed with rounding
0715 * mode being set to RoundingMode.UNNECESSARY
0716 * @see java.text.FieldPosition
0717 */
0718 private StringBuffer format(BigDecimal number, StringBuffer result,
0719 FieldPosition fieldPosition) {
0720 fieldPosition.setBeginIndex(0);
0721 fieldPosition.setEndIndex(0);
0722 return format(number, result, fieldPosition.getFieldDelegate());
0723 }
0724
0725 /**
0726 * Formats a BigDecimal to produce a string.
0727 * @param number The BigDecimal to format
0728 * @param result where the text is to be appended
0729 * @param delegate notified of locations of sub fields
0730 * @exception ArithmeticException if rounding is needed with rounding
0731 * mode being set to RoundingMode.UNNECESSARY
0732 * @return The formatted number string
0733 */
0734 private StringBuffer format(BigDecimal number, StringBuffer result,
0735 FieldDelegate delegate) {
0736 if (multiplier != 1) {
0737 number = number.multiply(getBigDecimalMultiplier());
0738 }
0739 boolean isNegative = number.signum() == -1;
0740 if (isNegative) {
0741 number = number.negate();
0742 }
0743
0744 synchronized (digitList) {
0745 int maxIntDigits = getMaximumIntegerDigits();
0746 int minIntDigits = getMinimumIntegerDigits();
0747 int maxFraDigits = getMaximumFractionDigits();
0748 int minFraDigits = getMinimumFractionDigits();
0749 int maximumDigits = maxIntDigits + maxFraDigits;
0750
0751 digitList
0752 .set(
0753 isNegative,
0754 number,
0755 useExponentialNotation ? ((maximumDigits < 0) ? Integer.MAX_VALUE
0756 : maximumDigits)
0757 : maxFraDigits,
0758 !useExponentialNotation);
0759
0760 return subformat(result, delegate, isNegative, false,
0761 maxIntDigits, minIntDigits, maxFraDigits,
0762 minFraDigits);
0763 }
0764 }
0765
0766 /**
0767 * Format a BigInteger to produce a string.
0768 * @param number The BigInteger to format
0769 * @param result where the text is to be appended
0770 * @param fieldPosition On input: an alignment field, if desired.
0771 * On output: the offsets of the alignment field.
0772 * @return The formatted number string
0773 * @exception ArithmeticException if rounding is needed with rounding
0774 * mode being set to RoundingMode.UNNECESSARY
0775 * @see java.text.FieldPosition
0776 */
0777 private StringBuffer format(BigInteger number, StringBuffer result,
0778 FieldPosition fieldPosition) {
0779 fieldPosition.setBeginIndex(0);
0780 fieldPosition.setEndIndex(0);
0781
0782 return format(number, result, fieldPosition.getFieldDelegate(),
0783 false);
0784 }
0785
0786 /**
0787 * Format a BigInteger to produce a string.
0788 * @param number The BigInteger to format
0789 * @param result where the text is to be appended
0790 * @param delegate notified of locations of sub fields
0791 * @return The formatted number string
0792 * @exception ArithmeticException if rounding is needed with rounding
0793 * mode being set to RoundingMode.UNNECESSARY
0794 * @see java.text.FieldPosition
0795 */
0796 private StringBuffer format(BigInteger number, StringBuffer result,
0797 FieldDelegate delegate, boolean formatLong) {
0798 if (multiplier != 1) {
0799 number = number.multiply(getBigIntegerMultiplier());
0800 }
0801 boolean isNegative = number.signum() == -1;
0802 if (isNegative) {
0803 number = number.negate();
0804 }
0805
0806 synchronized (digitList) {
0807 int maxIntDigits, minIntDigits, maxFraDigits, minFraDigits, maximumDigits;
0808 if (formatLong) {
0809 maxIntDigits = super .getMaximumIntegerDigits();
0810 minIntDigits = super .getMinimumIntegerDigits();
0811 maxFraDigits = super .getMaximumFractionDigits();
0812 minFraDigits = super .getMinimumFractionDigits();
0813 maximumDigits = maxIntDigits + maxFraDigits;
0814 } else {
0815 maxIntDigits = getMaximumIntegerDigits();
0816 minIntDigits = getMinimumIntegerDigits();
0817 maxFraDigits = getMaximumFractionDigits();
0818 minFraDigits = getMinimumFractionDigits();
0819 maximumDigits = maxIntDigits + maxFraDigits;
0820 if (maximumDigits < 0) {
0821 maximumDigits = Integer.MAX_VALUE;
0822 }
0823 }
0824
0825 digitList.set(isNegative, number,
0826 useExponentialNotation ? maximumDigits : 0);
0827
0828 return subformat(result, delegate, isNegative, true,
0829 maxIntDigits, minIntDigits, maxFraDigits,
0830 minFraDigits);
0831 }
0832 }
0833
0834 /**
0835 * Formats an Object producing an <code>AttributedCharacterIterator</code>.
0836 * You can use the returned <code>AttributedCharacterIterator</code>
0837 * to build the resulting String, as well as to determine information
0838 * about the resulting String.
0839 * <p>
0840 * Each attribute key of the AttributedCharacterIterator will be of type
0841 * <code>NumberFormat.Field</code>, with the attribute value being the
0842 * same as the attribute key.
0843 *
0844 * @exception NullPointerException if obj is null.
0845 * @exception IllegalArgumentException when the Format cannot format the
0846 * given object.
0847 * @exception ArithmeticException if rounding is needed with rounding
0848 * mode being set to RoundingMode.UNNECESSARY
0849 * @param obj The object to format
0850 * @return AttributedCharacterIterator describing the formatted value.
0851 * @since 1.4
0852 */
0853 public AttributedCharacterIterator formatToCharacterIterator(
0854 Object obj) {
0855 CharacterIteratorFieldDelegate delegate = new CharacterIteratorFieldDelegate();
0856 StringBuffer sb = new StringBuffer();
0857
0858 if (obj instanceof Double || obj instanceof Float) {
0859 format(((Number) obj).doubleValue(), sb, delegate);
0860 } else if (obj instanceof Long || obj instanceof Integer
0861 || obj instanceof Short || obj instanceof Byte
0862 || obj instanceof AtomicInteger
0863 || obj instanceof AtomicLong) {
0864 format(((Number) obj).longValue(), sb, delegate);
0865 } else if (obj instanceof BigDecimal) {
0866 format((BigDecimal) obj, sb, delegate);
0867 } else if (obj instanceof BigInteger) {
0868 format((BigInteger) obj, sb, delegate, false);
0869 } else if (obj == null) {
0870 throw new NullPointerException(
0871 "formatToCharacterIterator must be passed non-null object");
0872 } else {
0873 throw new IllegalArgumentException(
0874 "Cannot format given Object as a Number");
0875 }
0876 return delegate.getIterator(sb.toString());
0877 }
0878
0879 /**
0880 * Complete the formatting of a finite number. On entry, the digitList must
0881 * be filled in with the correct digits.
0882 */
0883 private StringBuffer subformat(StringBuffer result,
0884 FieldDelegate delegate, boolean isNegative,
0885 boolean isInteger, int maxIntDigits, int minIntDigits,
0886 int maxFraDigits, int minFraDigits) {
0887 // NOTE: This isn't required anymore because DigitList takes care of this.
0888 //
0889 // // The negative of the exponent represents the number of leading
0890 // // zeros between the decimal and the first non-zero digit, for
0891 // // a value < 0.1 (e.g., for 0.00123, -fExponent == 2). If this
0892 // // is more than the maximum fraction digits, then we have an underflow
0893 // // for the printed representation. We recognize this here and set
0894 // // the DigitList representation to zero in this situation.
0895 //
0896 // if (-digitList.decimalAt >= getMaximumFractionDigits())
0897 // {
0898 // digitList.count = 0;
0899 // }
0900
0901 char zero = symbols.getZeroDigit();
0902 int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
0903 char grouping = symbols.getGroupingSeparator();
0904 char decimal = isCurrencyFormat ? symbols
0905 .getMonetaryDecimalSeparator() : symbols
0906 .getDecimalSeparator();
0907
0908 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
0909 * format as zero. This allows sensible computations and preserves
0910 * relations such as signum(1/x) = signum(x), where x is +Infinity or
0911 * -Infinity. Prior to this fix, we always formatted zero values as if
0912 * they were positive. Liu 7/6/98.
0913 */
0914 if (digitList.isZero()) {
0915 digitList.decimalAt = 0; // Normalize
0916 }
0917
0918 if (isNegative) {
0919 append(result, negativePrefix, delegate,
0920 getNegativePrefixFieldPositions(), Field.SIGN);
0921 } else {
0922 append(result, positivePrefix, delegate,
0923 getPositivePrefixFieldPositions(), Field.SIGN);
0924 }
0925
0926 if (useExponentialNotation) {
0927 int iFieldStart = result.length();
0928 int iFieldEnd = -1;
0929 int fFieldStart = -1;
0930
0931 // Minimum integer digits are handled in exponential format by
0932 // adjusting the exponent. For example, 0.01234 with 3 minimum
0933 // integer digits is "123.4E-4".
0934
0935 // Maximum integer digits are interpreted as indicating the
0936 // repeating range. This is useful for engineering notation, in
0937 // which the exponent is restricted to a multiple of 3. For
0938 // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
0939 // If maximum integer digits are > 1 and are larger than
0940 // minimum integer digits, then minimum integer digits are
0941 // ignored.
0942 int exponent = digitList.decimalAt;
0943 int repeat = maxIntDigits;
0944 int minimumIntegerDigits = minIntDigits;
0945 if (repeat > 1 && repeat > minIntDigits) {
0946 // A repeating range is defined; adjust to it as follows.
0947 // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
0948 // -3,-4,-5=>-6, etc. This takes into account that the
0949 // exponent we have here is off by one from what we expect;
0950 // it is for the format 0.MMMMMx10^n.
0951 if (exponent >= 1) {
0952 exponent = ((exponent - 1) / repeat) * repeat;
0953 } else {
0954 // integer division rounds towards 0
0955 exponent = ((exponent - repeat) / repeat) * repeat;
0956 }
0957 minimumIntegerDigits = 1;
0958 } else {
0959 // No repeating range is defined; use minimum integer digits.
0960 exponent -= minimumIntegerDigits;
0961 }
0962
0963 // We now output a minimum number of digits, and more if there
0964 // are more digits, up to the maximum number of digits. We
0965 // place the decimal point after the "integer" digits, which
0966 // are the first (decimalAt - exponent) digits.
0967 int minimumDigits = minIntDigits + minFraDigits;
0968 if (minimumDigits < 0) { // overflow?
0969 minimumDigits = Integer.MAX_VALUE;
0970 }
0971
0972 // The number of integer digits is handled specially if the number
0973 // is zero, since then there may be no digits.
0974 int integerDigits = digitList.isZero() ? minimumIntegerDigits
0975 : digitList.decimalAt - exponent;
0976 if (minimumDigits < integerDigits) {
0977 minimumDigits = integerDigits;
0978 }
0979 int totalDigits = digitList.count;
0980 if (minimumDigits > totalDigits) {
0981 totalDigits = minimumDigits;
0982 }
0983 boolean addedDecimalSeparator = false;
0984
0985 for (int i = 0; i < totalDigits; ++i) {
0986 if (i == integerDigits) {
0987 // Record field information for caller.
0988 iFieldEnd = result.length();
0989
0990 result.append(decimal);
0991 addedDecimalSeparator = true;
0992
0993 // Record field information for caller.
0994 fFieldStart = result.length();
0995 }
0996 result
0997 .append((i < digitList.count) ? (char) (digitList.digits[i] + zeroDelta)
0998 : zero);
0999 }
1000
1001 if (decimalSeparatorAlwaysShown
1002 && totalDigits == integerDigits) {
1003 // Record field information for caller.
1004 iFieldEnd = result.length();
1005
1006 result.append(decimal);
1007 addedDecimalSeparator = true;
1008
1009 // Record field information for caller.
1010 fFieldStart = result.length();
1011 }
1012
1013 // Record field information
1014 if (iFieldEnd == -1) {
1015 iFieldEnd = result.length();
1016 }
1017 delegate.formatted(INTEGER_FIELD, Field.INTEGER,
1018 Field.INTEGER, iFieldStart, iFieldEnd, result);
1019 if (addedDecimalSeparator) {
1020 delegate.formatted(Field.DECIMAL_SEPARATOR,
1021 Field.DECIMAL_SEPARATOR, iFieldEnd,
1022 fFieldStart, result);
1023 }
1024 if (fFieldStart == -1) {
1025 fFieldStart = result.length();
1026 }
1027 delegate.formatted(FRACTION_FIELD, Field.FRACTION,
1028 Field.FRACTION, fFieldStart, result.length(),
1029 result);
1030
1031 // The exponent is output using the pattern-specified minimum
1032 // exponent digits. There is no maximum limit to the exponent
1033 // digits, since truncating the exponent would result in an
1034 // unacceptable inaccuracy.
1035 int fieldStart = result.length();
1036
1037 result.append(symbols.getExponentSeparator());
1038
1039 delegate.formatted(Field.EXPONENT_SYMBOL,
1040 Field.EXPONENT_SYMBOL, fieldStart, result.length(),
1041 result);
1042
1043 // For zero values, we force the exponent to zero. We
1044 // must do this here, and not earlier, because the value
1045 // is used to determine integer digit count above.
1046 if (digitList.isZero()) {
1047 exponent = 0;
1048 }
1049
1050 boolean negativeExponent = exponent < 0;
1051 if (negativeExponent) {
1052 exponent = -exponent;
1053 fieldStart = result.length();
1054 result.append(symbols.getMinusSign());
1055 delegate.formatted(Field.EXPONENT_SIGN,
1056 Field.EXPONENT_SIGN, fieldStart, result
1057 .length(), result);
1058 }
1059 digitList.set(negativeExponent, exponent);
1060
1061 int eFieldStart = result.length();
1062
1063 for (int i = digitList.decimalAt; i < minExponentDigits; ++i) {
1064 result.append(zero);
1065 }
1066 for (int i = 0; i < digitList.decimalAt; ++i) {
1067 result
1068 .append((i < digitList.count) ? (char) (digitList.digits[i] + zeroDelta)
1069 : zero);
1070 }
1071 delegate.formatted(Field.EXPONENT, Field.EXPONENT,
1072 eFieldStart, result.length(), result);
1073 } else {
1074 int iFieldStart = result.length();
1075
1076 // Output the integer portion. Here 'count' is the total
1077 // number of integer digits we will display, including both
1078 // leading zeros required to satisfy getMinimumIntegerDigits,
1079 // and actual digits present in the number.
1080 int count = minIntDigits;
1081 int digitIndex = 0; // Index into digitList.fDigits[]
1082 if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
1083 count = digitList.decimalAt;
1084 }
1085
1086 // Handle the case where getMaximumIntegerDigits() is smaller
1087 // than the real number of integer digits. If this is so, we
1088 // output the least significant max integer digits. For example,
1089 // the value 1997 printed with 2 max integer digits is just "97".
1090 if (count > maxIntDigits) {
1091 count = maxIntDigits;
1092 digitIndex = digitList.decimalAt - count;
1093 }
1094
1095 int sizeBeforeIntegerPart = result.length();
1096 for (int i = count - 1; i >= 0; --i) {
1097 if (i < digitList.decimalAt
1098 && digitIndex < digitList.count) {
1099 // Output a real digit
1100 result
1101 .append((char) (digitList.digits[digitIndex++] + zeroDelta));
1102 } else {
1103 // Output a leading zero
1104 result.append(zero);
1105 }
1106
1107 // Output grouping separator if necessary. Don't output a
1108 // grouping separator if i==0 though; that's at the end of
1109 // the integer part.
1110 if (isGroupingUsed() && i > 0 && (groupingSize != 0)
1111 && (i % groupingSize == 0)) {
1112 int gStart = result.length();
1113 result.append(grouping);
1114 delegate.formatted(Field.GROUPING_SEPARATOR,
1115 Field.GROUPING_SEPARATOR, gStart, result
1116 .length(), result);
1117 }
1118 }
1119
1120 // Determine whether or not there are any printable fractional
1121 // digits. If we've used up the digits we know there aren't.
1122 boolean fractionPresent = (minFraDigits > 0)
1123 || (!isInteger && digitIndex < digitList.count);
1124
1125 // If there is no fraction present, and we haven't printed any
1126 // integer digits, then print a zero. Otherwise we won't print
1127 // _any_ digits, and we won't be able to parse this string.
1128 if (!fractionPresent
1129 && result.length() == sizeBeforeIntegerPart) {
1130 result.append(zero);
1131 }
1132
1133 delegate
1134 .formatted(INTEGER_FIELD, Field.INTEGER,
1135 Field.INTEGER, iFieldStart,
1136 result.length(), result);
1137
1138 // Output the decimal separator if we always do so.
1139 int sStart = result.length();
1140 if (decimalSeparatorAlwaysShown || fractionPresent) {
1141 result.append(decimal);
1142 }
1143
1144 if (sStart != result.length()) {
1145 delegate.formatted(Field.DECIMAL_SEPARATOR,
1146 Field.DECIMAL_SEPARATOR, sStart, result
1147 .length(), result);
1148 }
1149 int fFieldStart = result.length();
1150
1151 for (int i = 0; i < maxFraDigits; ++i) {
1152 // Here is where we escape from the loop. We escape if we've
1153 // output the maximum fraction digits (specified in the for
1154 // expression above).
1155 // We also stop when we've output the minimum digits and either:
1156 // we have an integer, so there is no fractional stuff to
1157 // display, or we're out of significant digits.
1158 if (i >= minFraDigits
1159 && (isInteger || digitIndex >= digitList.count)) {
1160 break;
1161 }
1162
1163 // Output leading fractional zeros. These are zeros that come
1164 // after the decimal but before any significant digits. These
1165 // are only output if abs(number being formatted) < 1.0.
1166 if (-1 - i > (digitList.decimalAt - 1)) {
1167 result.append(zero);
1168 continue;
1169 }
1170
1171 // Output a digit, if we have any precision left, or a
1172 // zero if we don't. We don't want to output noise digits.
1173 if (!isInteger && digitIndex < digitList.count) {
1174 result
1175 .append((char) (digitList.digits[digitIndex++] + zeroDelta));
1176 } else {
1177 result.append(zero);
1178 }
1179 }
1180
1181 // Record field information for caller.
1182 delegate.formatted(FRACTION_FIELD, Field.FRACTION,
1183 Field.FRACTION, fFieldStart, result.length(),
1184 result);
1185 }
1186
1187 if (isNegative) {
1188 append(result, negativeSuffix, delegate,
1189 getNegativeSuffixFieldPositions(), Field.SIGN);
1190 } else {
1191 append(result, positiveSuffix, delegate,
1192 getPositiveSuffixFieldPositions(), Field.SIGN);
1193 }
1194
1195 return result;
1196 }
1197
1198 /**
1199 * Appends the String <code>string</code> to <code>result</code>.
1200 * <code>delegate</code> is notified of all the
1201 * <code>FieldPosition</code>s in <code>positions</code>.
1202 * <p>
1203 * If one of the <code>FieldPosition</code>s in <code>positions</code>
1204 * identifies a <code>SIGN</code> attribute, it is mapped to
1205 * <code>signAttribute</code>. This is used
1206 * to map the <code>SIGN</code> attribute to the <code>EXPONENT</code>
1207 * attribute as necessary.
1208 * <p>
1209 * This is used by <code>subformat</code> to add the prefix/suffix.
1210 */
1211 private void append(StringBuffer result, String string,
1212 FieldDelegate delegate, FieldPosition[] positions,
1213 Format.Field signAttribute) {
1214 int start = result.length();
1215
1216 if (string.length() > 0) {
1217 result.append(string);
1218 for (int counter = 0, max = positions.length; counter < max; counter++) {
1219 FieldPosition fp = positions[counter];
1220 Format.Field attribute = fp.getFieldAttribute();
1221
1222 if (attribute == Field.SIGN) {
1223 attribute = signAttribute;
1224 }
1225 delegate.formatted(attribute, attribute, start
1226 + fp.getBeginIndex(), start + fp.getEndIndex(),
1227 result);
1228 }
1229 }
1230 }
1231
1232 /**
1233 * Parses text from a string to produce a <code>Number</code>.
1234 * <p>
1235 * The method attempts to parse text starting at the index given by
1236 * <code>pos</code>.
1237 * If parsing succeeds, then the index of <code>pos</code> is updated
1238 * to the index after the last character used (parsing does not necessarily
1239 * use all characters up to the end of the string), and the parsed
1240 * number is returned. The updated <code>pos</code> can be used to
1241 * indicate the starting point for the next call to this method.
1242 * If an error occurs, then the index of <code>pos</code> is not
1243 * changed, the error index of <code>pos</code> is set to the index of
1244 * the character where the error occurred, and null is returned.
1245 * <p>
1246 * The subclass returned depends on the value of {@link #isParseBigDecimal}
1247 * as well as on the string being parsed.
1248 * <ul>
1249 * <li>If <code>isParseBigDecimal()</code> is false (the default),
1250 * most integer values are returned as <code>Long</code>
1251 * objects, no matter how they are written: <code>"17"</code> and
1252 * <code>"17.000"</code> both parse to <code>Long(17)</code>.
1253 * Values that cannot fit into a <code>Long</code> are returned as
1254 * <code>Double</code>s. This includes values with a fractional part,
1255 * infinite values, <code>NaN</code>, and the value -0.0.
1256 * <code>DecimalFormat</code> does <em>not</em> decide whether to
1257 * return a <code>Double</code> or a <code>Long</code> based on the
1258 * presence of a decimal separator in the source string. Doing so
1259 * would prevent integers that overflow the mantissa of a double,
1260 * such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
1261 * parsed accurately.
1262 * <p>
1263 * Callers may use the <code>Number</code> methods
1264 * <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
1265 * the type they want.
1266 * <li>If <code>isParseBigDecimal()</code> is true, values are returned
1267 * as <code>BigDecimal</code> objects. The values are the ones
1268 * constructed by {@link java.math.BigDecimal#BigDecimal(String)}
1269 * for corresponding strings in locale-independent format. The
1270 * special cases negative and positive infinity and NaN are returned
1271 * as <code>Double</code> instances holding the values of the
1272 * corresponding <code>Double</code> constants.
1273 * </ul>
1274 * <p>
1275 * <code>DecimalFormat</code> parses all Unicode characters that represent
1276 * decimal digits, as defined by <code>Character.digit()</code>. In
1277 * addition, <code>DecimalFormat</code> also recognizes as digits the ten
1278 * consecutive characters starting with the localized zero digit defined in
1279 * the <code>DecimalFormatSymbols</code> object.
1280 *
1281 * @param text the string to be parsed
1282 * @param pos A <code>ParsePosition</code> object with index and error
1283 * index information as described above.
1284 * @return the parsed value, or <code>null</code> if the parse fails
1285 * @exception NullPointerException if <code>text</code> or
1286 * <code>pos</code> is null.
1287 */
1288 public Number parse(String text, ParsePosition pos) {
1289 // special case NaN
1290 if (text.regionMatches(pos.index, symbols.getNaN(), 0, symbols
1291 .getNaN().length())) {
1292 pos.index = pos.index + symbols.getNaN().length();
1293 return new Double(Double.NaN);
1294 }
1295
1296 boolean[] status = new boolean[STATUS_LENGTH];
1297 if (!subparse(text, pos, positivePrefix, negativePrefix,
1298 digitList, false, status)) {
1299 return null;
1300 }
1301
1302 // special case INFINITY
1303 if (status[STATUS_INFINITE]) {
1304 if (status[STATUS_POSITIVE] == (multiplier >= 0)) {
1305 return new Double(Double.POSITIVE_INFINITY);
1306 } else {
1307 return new Double(Double.NEGATIVE_INFINITY);
1308 }
1309 }
1310
1311 if (multiplier == 0) {
1312 if (digitList.isZero()) {
1313 return new Double(Double.NaN);
1314 } else if (status[STATUS_POSITIVE]) {
1315 return new Double(Double.POSITIVE_INFINITY);
1316 } else {
1317 return new Double(Double.NEGATIVE_INFINITY);
1318 }
1319 }
1320
1321 if (isParseBigDecimal()) {
1322 BigDecimal bigDecimalResult = digitList.getBigDecimal();
1323
1324 if (multiplier != 1) {
1325 try {
1326 bigDecimalResult = bigDecimalResult
1327 .divide(getBigDecimalMultiplier());
1328 } catch (ArithmeticException e) { // non-terminating decimal expansion
1329 bigDecimalResult = bigDecimalResult.divide(
1330 getBigDecimalMultiplier(), roundingMode);
1331 }
1332 }
1333
1334 if (!status[STATUS_POSITIVE]) {
1335 bigDecimalResult = bigDecimalResult.negate();
1336 }
1337 return bigDecimalResult;
1338 } else {
1339 boolean gotDouble = true;
1340 boolean gotLongMinimum = false;
1341 double doubleResult = 0.0;
1342 long longResult = 0;
1343
1344 // Finally, have DigitList parse the digits into a value.
1345 if (digitList.fitsIntoLong(status[STATUS_POSITIVE],
1346 isParseIntegerOnly())) {
1347 gotDouble = false;
1348 longResult = digitList.getLong();
1349 if (longResult < 0) { // got Long.MIN_VALUE
1350 gotLongMinimum = true;
1351 }
1352 } else {
1353 doubleResult = digitList.getDouble();
1354 }
1355
1356 // Divide by multiplier. We have to be careful here not to do
1357 // unneeded conversions between double and long.
1358 if (multiplier != 1) {
1359 if (gotDouble) {
1360 doubleResult /= multiplier;
1361 } else {
1362 // Avoid converting to double if we can
1363 if (longResult % multiplier == 0) {
1364 longResult /= multiplier;
1365 } else {
1366 doubleResult = ((double) longResult)
1367 / multiplier;
1368 gotDouble = true;
1369 }
1370 }
1371 }
1372
1373 if (!status[STATUS_POSITIVE] && !gotLongMinimum) {
1374 doubleResult = -doubleResult;
1375 longResult = -longResult;
1376 }
1377
1378 // At this point, if we divided the result by the multiplier, the
1379 // result may fit into a long. We check for this case and return
1380 // a long if possible.
1381 // We must do this AFTER applying the negative (if appropriate)
1382 // in order to handle the case of LONG_MIN; otherwise, if we do
1383 // this with a positive value -LONG_MIN, the double is > 0, but
1384 // the long is < 0. We also must retain a double in the case of
1385 // -0.0, which will compare as == to a long 0 cast to a double
1386 // (bug 4162852).
1387 if (multiplier != 1 && gotDouble) {
1388 longResult = (long) doubleResult;
1389 gotDouble = ((doubleResult != (double) longResult) || (doubleResult == 0.0 && 1 / doubleResult < 0.0))
1390 && !isParseIntegerOnly();
1391 }
1392
1393 return gotDouble ? (Number) new Double(doubleResult)
1394 : (Number) new Long(longResult);
1395 }
1396 }
1397
1398 /**
1399 * Return a BigInteger multiplier.
1400 */
1401 private BigInteger getBigIntegerMultiplier() {
1402 if (bigIntegerMultiplier == null) {
1403 bigIntegerMultiplier = BigInteger.valueOf(multiplier);
1404 }
1405 return bigIntegerMultiplier;
1406 }
1407
1408 private transient BigInteger bigIntegerMultiplier;
1409
1410 /**
1411 * Return a BigDecimal multiplier.
1412 */
1413 private BigDecimal getBigDecimalMultiplier() {
1414 if (bigDecimalMultiplier == null) {
1415 bigDecimalMultiplier = new BigDecimal(multiplier);
1416 }
1417 return bigDecimalMultiplier;
1418 }
1419
1420 private transient BigDecimal bigDecimalMultiplier;
1421
1422 private static final int STATUS_INFINITE = 0;
1423 private static final int STATUS_POSITIVE = 1;
1424 private static final int STATUS_LENGTH = 2;
1425
1426 /**
1427 * Parse the given text into a number. The text is parsed beginning at
1428 * parsePosition, until an unparseable character is seen.
1429 * @param text The string to parse.
1430 * @param parsePosition The position at which to being parsing. Upon
1431 * return, the first unparseable character.
1432 * @param digits The DigitList to set to the parsed value.
1433 * @param isExponent If true, parse an exponent. This means no
1434 * infinite values and integer only.
1435 * @param status Upon return contains boolean status flags indicating
1436 * whether the value was infinite and whether it was positive.
1437 */
1438 private final boolean subparse(String text,
1439 ParsePosition parsePosition, String positivePrefix,
1440 String negativePrefix, DigitList digits,
1441 boolean isExponent, boolean status[]) {
1442 int position = parsePosition.index;
1443 int oldStart = parsePosition.index;
1444 int backup;
1445 boolean gotPositive, gotNegative;
1446
1447 // check for positivePrefix; take longest
1448 gotPositive = text.regionMatches(position, positivePrefix, 0,
1449 positivePrefix.length());
1450 gotNegative = text.regionMatches(position, negativePrefix, 0,
1451 negativePrefix.length());
1452
1453 if (gotPositive && gotNegative) {
1454 if (positivePrefix.length() > negativePrefix.length()) {
1455 gotNegative = false;
1456 } else if (positivePrefix.length() < negativePrefix
1457 .length()) {
1458 gotPositive = false;
1459 }
1460 }
1461
1462 if (gotPositive) {
1463 position += positivePrefix.length();
1464 } else if (gotNegative) {
1465 position += negativePrefix.length();
1466 } else {
1467 parsePosition.errorIndex = position;
1468 return false;
1469 }
1470
1471 // process digits or Inf, find decimal position
1472 status[STATUS_INFINITE] = false;
1473 if (!isExponent
1474 && text.regionMatches(position, symbols.getInfinity(),
1475 0, symbols.getInfinity().length())) {
1476 position += symbols.getInfinity().length();
1477 status[STATUS_INFINITE] = true;
1478 } else {
1479 // We now have a string of digits, possibly with grouping symbols,
1480 // and decimal points. We want to process these into a DigitList.
1481 // We don't want to put a bunch of leading zeros into the DigitList
1482 // though, so we keep track of the location of the decimal point,
1483 // put only significant digits into the DigitList, and adjust the
1484 // exponent as needed.
1485
1486 digits.decimalAt = digits.count = 0;
1487 char zero = symbols.getZeroDigit();
1488 char decimal = isCurrencyFormat ? symbols
1489 .getMonetaryDecimalSeparator() : symbols
1490 .getDecimalSeparator();
1491 char grouping = symbols.getGroupingSeparator();
1492 String exponentString = symbols.getExponentSeparator();
1493 boolean sawDecimal = false;
1494 boolean sawExponent = false;
1495 boolean sawDigit = false;
1496 int exponent = 0; // Set to the exponent value, if any
1497
1498 // We have to track digitCount ourselves, because digits.count will
1499 // pin when the maximum allowable digits is reached.
1500 int digitCount = 0;
1501
1502 backup = -1;
1503 for (; position < text.length(); ++position) {
1504 char ch = text.charAt(position);
1505
1506 /* We recognize all digit ranges, not only the Latin digit range
1507 * '0'..'9'. We do so by using the Character.digit() method,
1508 * which converts a valid Unicode digit to the range 0..9.
1509 *
1510 * The character 'ch' may be a digit. If so, place its value
1511 * from 0 to 9 in 'digit'. First try using the locale digit,
1512 * which may or MAY NOT be a standard Unicode digit range. If
1513 * this fails, try using the standard Unicode digit ranges by
1514 * calling Character.digit(). If this also fails, digit will
1515 * have a value outside the range 0..9.
1516 */
1517 int digit = ch - zero;
1518 if (digit < 0 || digit > 9) {
1519 digit = Character.digit(ch, 10);
1520 }
1521
1522 if (digit == 0) {
1523 // Cancel out backup setting (see grouping handler below)
1524 backup = -1; // Do this BEFORE continue statement below!!!
1525 sawDigit = true;
1526
1527 // Handle leading zeros
1528 if (digits.count == 0) {
1529 // Ignore leading zeros in integer part of number.
1530 if (!sawDecimal) {
1531 continue;
1532 }
1533
1534 // If we have seen the decimal, but no significant
1535 // digits yet, then we account for leading zeros by
1536 // decrementing the digits.decimalAt into negative
1537 // values.
1538 --digits.decimalAt;
1539 } else {
1540 ++digitCount;
1541 digits.append((char) (digit + '0'));
1542 }
1543 } else if (digit > 0 && digit <= 9) { // [sic] digit==0 handled above
1544 sawDigit = true;
1545 ++digitCount;
1546 digits.append((char) (digit + '0'));
1547
1548 // Cancel out backup setting (see grouping handler below)
1549 backup = -1;
1550 } else if (!isExponent && ch == decimal) {
1551 // If we're only parsing integers, or if we ALREADY saw the
1552 // decimal, then don't parse this one.
1553 if (isParseIntegerOnly() || sawDecimal) {
1554 break;
1555 }
1556 digits.decimalAt = digitCount; // Not digits.count!
1557 sawDecimal = true;
1558 } else if (!isExponent && ch == grouping
1559 && isGroupingUsed()) {
1560 if (sawDecimal) {
1561 break;
1562 }
1563 // Ignore grouping characters, if we are using them, but
1564 // require that they be followed by a digit. Otherwise
1565 // we backup and reprocess them.
1566 backup = position;
1567 } else if (!isExponent
1568 && text.regionMatches(position, exponentString,
1569 0, exponentString.length())
1570 && !sawExponent) {
1571 // Process the exponent by recursively calling this method.
1572 ParsePosition pos = new ParsePosition(position
1573 + exponentString.length());
1574 boolean[] stat = new boolean[STATUS_LENGTH];
1575 DigitList exponentDigits = new DigitList();
1576
1577 if (subparse(text, pos, "", Character
1578 .toString(symbols.getMinusSign()),
1579 exponentDigits, true, stat)
1580 && exponentDigits.fitsIntoLong(
1581 stat[STATUS_POSITIVE], true)) {
1582 position = pos.index; // Advance past the exponent
1583 exponent = (int) exponentDigits.getLong();
1584 if (!stat[STATUS_POSITIVE]) {
1585 exponent = -exponent;
1586 }
1587 sawExponent = true;
1588 }
1589 break; // Whether we fail or succeed, we exit this loop
1590 } else {
1591 break;
1592 }
1593 }
1594
1595 if (backup != -1) {
1596 position = backup;
1597 }
1598
1599 // If there was no decimal point we have an integer
1600 if (!sawDecimal) {
1601 digits.decimalAt = digitCount; // Not digits.count!
1602 }
1603
1604 // Adjust for exponent, if any
1605 digits.decimalAt += exponent;
1606
1607 // If none of the text string was recognized. For example, parse
1608 // "x" with pattern "#0.00" (return index and error index both 0)
1609 // parse "$" with pattern "$#0.00". (return index 0 and error
1610 // index 1).
1611 if (!sawDigit && digitCount == 0) {
1612 parsePosition.index = oldStart;
1613 parsePosition.errorIndex = oldStart;
1614 return false;
1615 }
1616 }
1617
1618 // check for suffix
1619 if (!isExponent) {
1620 if (gotPositive) {
1621 gotPositive = text.regionMatches(position,
1622 positiveSuffix, 0, positiveSuffix.length());
1623 }
1624 if (gotNegative) {
1625 gotNegative = text.regionMatches(position,
1626 negativeSuffix, 0, negativeSuffix.length());
1627 }
1628
1629 // if both match, take longest
1630 if (gotPositive && gotNegative) {
1631 if (positiveSuffix.length() > negativeSuffix.length()) {
1632 gotNegative = false;
1633 } else if (positiveSuffix.length() < negativeSuffix
1634 .length()) {
1635 gotPositive = false;
1636 }
1637 }
1638
1639 // fail if neither or both
1640 if (gotPositive == gotNegative) {
1641 parsePosition.errorIndex = position;
1642 return false;
1643 }
1644
1645 parsePosition.index = position
1646 + (gotPositive ? positiveSuffix.length()
1647 : negativeSuffix.length()); // mark success!
1648 } else {
1649 parsePosition.index = position;
1650 }
1651
1652 status[STATUS_POSITIVE] = gotPositive;
1653 if (parsePosition.index == oldStart) {
1654 parsePosition.errorIndex = position;
1655 return false;
1656 }
1657 return true;
1658 }
1659
1660 /**
1661 * Returns a copy of the decimal format symbols, which is generally not
1662 * changed by the programmer or user.
1663 * @return a copy of the desired DecimalFormatSymbols
1664 * @see java.text.DecimalFormatSymbols
1665 */
1666 public DecimalFormatSymbols getDecimalFormatSymbols() {
1667 try {
1668 // don't allow multiple references
1669 return (DecimalFormatSymbols) symbols.clone();
1670 } catch (Exception foo) {
1671 return null; // should never happen
1672 }
1673 }
1674
1675 /**
1676 * Sets the decimal format symbols, which is generally not changed
1677 * by the programmer or user.
1678 * @param newSymbols desired DecimalFormatSymbols
1679 * @see java.text.DecimalFormatSymbols
1680 */
1681 public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
1682 try {
1683 // don't allow multiple references
1684 symbols = (DecimalFormatSymbols) newSymbols.clone();
1685 expandAffixes();
1686 } catch (Exception foo) {
1687 // should never happen
1688 }
1689 }
1690
1691 /**
1692 * Get the positive prefix.
1693 * <P>Examples: +123, $123, sFr123
1694 */
1695 public String getPositivePrefix() {
1696 return positivePrefix;
1697 }
1698
1699 /**
1700 * Set the positive prefix.
1701 * <P>Examples: +123, $123, sFr123
1702 */
1703 public void setPositivePrefix(String newValue) {
1704 positivePrefix = newValue;
1705 posPrefixPattern = null;
1706 positivePrefixFieldPositions = null;
1707 }
1708
1709 /**
1710 * Returns the FieldPositions of the fields in the prefix used for
1711 * positive numbers. This is not used if the user has explicitly set
1712 * a positive prefix via <code>setPositivePrefix</code>. This is
1713 * lazily created.
1714 *
1715 * @return FieldPositions in positive prefix
1716 */
1717 private FieldPosition[] getPositivePrefixFieldPositions() {
1718 if (positivePrefixFieldPositions == null) {
1719 if (posPrefixPattern != null) {
1720 positivePrefixFieldPositions = expandAffix(posPrefixPattern);
1721 } else {
1722 positivePrefixFieldPositions = EmptyFieldPositionArray;
1723 }
1724 }
1725 return positivePrefixFieldPositions;
1726 }
1727
1728 /**
1729 * Get the negative prefix.
1730 * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1731 */
1732 public String getNegativePrefix() {
1733 return negativePrefix;
1734 }
1735
1736 /**
1737 * Set the negative prefix.
1738 * <P>Examples: -123, ($123) (with negative suffix), sFr-123
1739 */
1740 public void setNegativePrefix(String newValue) {
1741 negativePrefix = newValue;
1742 negPrefixPattern = null;
1743 }
1744
1745 /**
1746 * Returns the FieldPositions of the fields in the prefix used for
1747 * negative numbers. This is not used if the user has explicitly set
1748 * a negative prefix via <code>setNegativePrefix</code>. This is
1749 * lazily created.
1750 *
1751 * @return FieldPositions in positive prefix
1752 */
1753 private FieldPosition[] getNegativePrefixFieldPositions() {
1754 if (negativePrefixFieldPositions == null) {
1755 if (negPrefixPattern != null) {
1756 negativePrefixFieldPositions = expandAffix(negPrefixPattern);
1757 } else {
1758 negativePrefixFieldPositions = EmptyFieldPositionArray;
1759 }
1760 }
1761 return negativePrefixFieldPositions;
1762 }
1763
1764 /**
1765 * Get the positive suffix.
1766 * <P>Example: 123%
1767 */
1768 public String getPositiveSuffix() {
1769 return positiveSuffix;
1770 }
1771
1772 /**
1773 * Set the positive suffix.
1774 * <P>Example: 123%
1775 */
1776 public void setPositiveSuffix(String newValue) {
1777 positiveSuffix = newValue;
1778 posSuffixPattern = null;
1779 }
1780
1781 /**
1782 * Returns the FieldPositions of the fields in the suffix used for
1783 * positive numbers. This is not used if the user has explicitly set
1784 * a positive suffix via <code>setPositiveSuffix</code>. This is
1785 * lazily created.
1786 *
1787 * @return FieldPositions in positive prefix
1788 */
1789 private FieldPosition[] getPositiveSuffixFieldPositions() {
1790 if (positiveSuffixFieldPositions == null) {
1791 if (posSuffixPattern != null) {
1792 positiveSuffixFieldPositions = expandAffix(posSuffixPattern);
1793 } else {
1794 positiveSuffixFieldPositions = EmptyFieldPositionArray;
1795 }
1796 }
1797 return positiveSuffixFieldPositions;
1798 }
1799
1800 /**
1801 * Get the negative suffix.
1802 * <P>Examples: -123%, ($123) (with positive suffixes)
1803 */
1804 public String getNegativeSuffix() {
1805 return negativeSuffix;
1806 }
1807
1808 /**
1809 * Set the negative suffix.
1810 * <P>Examples: 123%
1811 */
1812 public void setNegativeSuffix(String newValue) {
1813 negativeSuffix = newValue;
1814 negSuffixPattern = null;
1815 }
1816
1817 /**
1818 * Returns the FieldPositions of the fields in the suffix used for
1819 * negative numbers. This is not used if the user has explicitly set
1820 * a negative suffix via <code>setNegativeSuffix</code>. This is
1821 * lazily created.
1822 *
1823 * @return FieldPositions in positive prefix
1824 */
1825 private FieldPosition[] getNegativeSuffixFieldPositions() {
1826 if (negativeSuffixFieldPositions == null) {
1827 if (negSuffixPattern != null) {
1828 negativeSuffixFieldPositions = expandAffix(negSuffixPattern);
1829 } else {
1830 negativeSuffixFieldPositions = EmptyFieldPositionArray;
1831 }
1832 }
1833 return negativeSuffixFieldPositions;
1834 }
1835
1836 /**
1837 * Gets the multiplier for use in percent, per mille, and similar
1838 * formats.
1839 *
1840 * @see #setMultiplier(int)
1841 */
1842 public int getMultiplier() {
1843 return multiplier;
1844 }
1845
1846 /**
1847 * Sets the multiplier for use in percent, per mille, and similar
1848 * formats.
1849 * For a percent format, set the multiplier to 100 and the suffixes to
1850 * have '%' (for Arabic, use the Arabic percent sign).
1851 * For a per mille format, set the multiplier to 1000 and the suffixes to
1852 * have '\u2030'.
1853 *
1854 * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
1855 * "123" is parsed into 1.23.
1856 *
1857 * @see #getMultiplier
1858 */
1859 public void setMultiplier(int newValue) {
1860 multiplier = newValue;
1861 bigDecimalMultiplier = null;
1862 bigIntegerMultiplier = null;
1863 }
1864
1865 /**
1866 * Return the grouping size. Grouping size is the number of digits between
1867 * grouping separators in the integer portion of a number. For example,
1868 * in the number "123,456.78", the grouping size is 3.
1869 * @see #setGroupingSize
1870 * @see java.text.NumberFormat#isGroupingUsed
1871 * @see java.text.DecimalFormatSymbols#getGroupingSeparator
1872 */
1873 public int getGroupingSize() {
1874 return groupingSize;
1875 }
1876
1877 /**
1878 * Set the grouping size. Grouping size is the number of digits between
1879 * grouping separators in the integer portion of a number. For example,
1880 * in the number "123,456.78", the grouping size is 3.
1881 * <br>
1882 * The value passed in is converted to a byte, which may lose information.
1883 * @see #getGroupingSize
1884 * @see java.text.NumberFormat#setGroupingUsed
1885 * @see java.text.DecimalFormatSymbols#setGroupingSeparator
1886 */
1887 public void setGroupingSize(int newValue) {
1888 groupingSize = (byte) newValue;
1889 }
1890
1891 /**
1892 * Allows you to get the behavior of the decimal separator with integers.
1893 * (The decimal separator will always appear with decimals.)
1894 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1895 */
1896 public boolean isDecimalSeparatorAlwaysShown() {
1897 return decimalSeparatorAlwaysShown;
1898 }
1899
1900 /**
1901 * Allows you to set the behavior of the decimal separator with integers.
1902 * (The decimal separator will always appear with decimals.)
1903 * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
1904 */
1905 public void setDecimalSeparatorAlwaysShown(boolean newValue) {
1906 decimalSeparatorAlwaysShown = newValue;
1907 }
1908
1909 /**
1910 * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1911 * method returns <code>BigDecimal</code>. The default value is false.
1912 * @see #setParseBigDecimal
1913 * @since 1.5
1914 */
1915 public boolean isParseBigDecimal() {
1916 return parseBigDecimal;
1917 }
1918
1919 /**
1920 * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1921 * method returns <code>BigDecimal</code>.
1922 * @see #isParseBigDecimal
1923 * @since 1.5
1924 */
1925 public void setParseBigDecimal(boolean newValue) {
1926 parseBigDecimal = newValue;
1927 }
1928
1929 /**
1930 * Standard override; no change in semantics.
1931 */
1932 public Object clone() {
1933 try {
1934 DecimalFormat other = (DecimalFormat) super .clone();
1935 other.symbols = (DecimalFormatSymbols) symbols.clone();
1936 other.digitList = (DigitList) digitList.clone();
1937 return other;
1938 } catch (Exception e) {
1939 throw new InternalError();
1940 }
1941 }
1942
1943 /**
1944 * Overrides equals
1945 */
1946 public boolean equals(Object obj) {
1947 if (obj == null)
1948 return false;
1949 if (!super .equals(obj))
1950 return false; // super does class check
1951 DecimalFormat other = (DecimalFormat) obj;
1952 return ((posPrefixPattern == other.posPrefixPattern && positivePrefix
1953 .equals(other.positivePrefix)) || (posPrefixPattern != null && posPrefixPattern
1954 .equals(other.posPrefixPattern)))
1955 && ((posSuffixPattern == other.posSuffixPattern && positiveSuffix
1956 .equals(other.positiveSuffix)) || (posSuffixPattern != null && posSuffixPattern
1957 .equals(other.posSuffixPattern)))
1958 && ((negPrefixPattern == other.negPrefixPattern && negativePrefix
1959 .equals(other.negativePrefix)) || (negPrefixPattern != null && negPrefixPattern
1960 .equals(other.negPrefixPattern)))
1961 && ((negSuffixPattern == other.negSuffixPattern && negativeSuffix
1962 .equals(other.negativeSuffix)) || (negSuffixPattern != null && negSuffixPattern
1963 .equals(other.negSuffixPattern)))
1964 && multiplier == other.multiplier
1965 && groupingSize == other.groupingSize
1966 && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
1967 && parseBigDecimal == other.parseBigDecimal
1968 && useExponentialNotation == other.useExponentialNotation
1969 && (!useExponentialNotation || minExponentDigits == other.minExponentDigits)
1970 && maximumIntegerDigits == other.maximumIntegerDigits
1971 && minimumIntegerDigits == other.minimumIntegerDigits
1972 && maximumFractionDigits == other.maximumFractionDigits
1973 && minimumFractionDigits == other.minimumFractionDigits
1974 && roundingMode == other.roundingMode
1975 && symbols.equals(other.symbols);
1976 }
1977
1978 /**
1979 * Overrides hashCode
1980 */
1981 public int hashCode() {
1982 return super .hashCode() * 37 + positivePrefix.hashCode();
1983 // just enough fields for a reasonable distribution
1984 }
1985
1986 /**
1987 * Synthesizes a pattern string that represents the current state
1988 * of this Format object.
1989 * @see #applyPattern
1990 */
1991 public String toPattern() {
1992 return toPattern(false);
1993 }
1994
1995 /**
1996 * Synthesizes a localized pattern string that represents the current
1997 * state of this Format object.
1998 * @see #applyPattern
1999 */
2000 public String toLocalizedPattern() {
2001 return toPattern(true);
2002 }
2003
2004 /**
2005 * Expand the affix pattern strings into the expanded affix strings. If any
2006 * affix pattern string is null, do not expand it. This method should be
2007 * called any time the symbols or the affix patterns change in order to keep
2008 * the expanded affix strings up to date.
2009 */
2010 private void expandAffixes() {
2011 // Reuse one StringBuffer for better performance
2012 StringBuffer buffer = new StringBuffer();
2013 if (posPrefixPattern != null) {
2014 positivePrefix = expandAffix(posPrefixPattern, buffer);
2015 positivePrefixFieldPositions = null;
2016 }
2017 if (posSuffixPattern != null) {
2018 positiveSuffix = expandAffix(posSuffixPattern, buffer);
2019 positiveSuffixFieldPositions = null;
2020 }
2021 if (negPrefixPattern != null) {
2022 negativePrefix = expandAffix(negPrefixPattern, buffer);
2023 negativePrefixFieldPositions = null;
2024 }
2025 if (negSuffixPattern != null) {
2026 negativeSuffix = expandAffix(negSuffixPattern, buffer);
2027 negativeSuffixFieldPositions = null;
2028 }
2029 }
2030
2031 /**
2032 * Expand an affix pattern into an affix string. All characters in the
2033 * pattern are literal unless prefixed by QUOTE. The following characters
2034 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2035 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2036 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2037 * currency code. Any other character after a QUOTE represents itself.
2038 * QUOTE must be followed by another character; QUOTE may not occur by
2039 * itself at the end of the pattern.
2040 *
2041 * @param pattern the non-null, possibly empty pattern
2042 * @param buffer a scratch StringBuffer; its contents will be lost
2043 * @return the expanded equivalent of pattern
2044 */
2045 private String expandAffix(String pattern, StringBuffer buffer) {
2046 buffer.setLength(0);
2047 for (int i = 0; i < pattern.length();) {
2048 char c = pattern.charAt(i++);
2049 if (c == QUOTE) {
2050 c = pattern.charAt(i++);
2051 switch (c) {
2052 case CURRENCY_SIGN:
2053 if (i < pattern.length()
2054 && pattern.charAt(i) == CURRENCY_SIGN) {
2055 ++i;
2056 buffer.append(symbols
2057 .getInternationalCurrencySymbol());
2058 } else {
2059 buffer.append(symbols.getCurrencySymbol());
2060 }
2061 continue;
2062 case PATTERN_PERCENT:
2063 c = symbols.getPercent();
2064 break;
2065 case PATTERN_PER_MILLE:
2066 c = symbols.getPerMill();
2067 break;
2068 case PATTERN_MINUS:
2069 c = symbols.getMinusSign();
2070 break;
2071 }
2072 }
2073 buffer.append(c);
2074 }
2075 return buffer.toString();
2076 }
2077
2078 /**
2079 * Expand an affix pattern into an array of FieldPositions describing
2080 * how the pattern would be expanded.
2081 * All characters in the
2082 * pattern are literal unless prefixed by QUOTE. The following characters
2083 * after QUOTE are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2084 * PATTERN_MINUS, and CURRENCY_SIGN. If CURRENCY_SIGN is doubled (QUOTE +
2085 * CURRENCY_SIGN + CURRENCY_SIGN), it is interpreted as an ISO 4217
2086 * currency code. Any other character after a QUOTE represents itself.
2087 * QUOTE must be followed by another character; QUOTE may not occur by
2088 * itself at the end of the pattern.
2089 *
2090 * @param pattern the non-null, possibly empty pattern
2091 * @return FieldPosition array of the resulting fields.
2092 */
2093 private FieldPosition[] expandAffix(String pattern) {
2094 ArrayList positions = null;
2095 int stringIndex = 0;
2096 for (int i = 0; i < pattern.length();) {
2097 char c = pattern.charAt(i++);
2098 if (c == QUOTE) {
2099 int field = -1;
2100 Format.Field fieldID = null;
2101 c = pattern.charAt(i++);
2102 switch (c) {
2103 case CURRENCY_SIGN:
2104 String string;
2105 if (i < pattern.length()
2106 && pattern.charAt(i) == CURRENCY_SIGN) {
2107 ++i;
2108 string = symbols
2109 .getInternationalCurrencySymbol();
2110 } else {
2111 string = symbols.getCurrencySymbol();
2112 }
2113 if (string.length() > 0) {
2114 if (positions == null) {
2115 positions = new ArrayList(2);
2116 }
2117 FieldPosition fp = new FieldPosition(
2118 Field.CURRENCY);
2119 fp.setBeginIndex(stringIndex);
2120 fp.setEndIndex(stringIndex + string.length());
2121 positions.add(fp);
2122 stringIndex += string.length();
2123 }
2124 continue;
2125 case PATTERN_PERCENT:
2126 c = symbols.getPercent();
2127 field = -1;
2128 fieldID = Field.PERCENT;
2129 break;
2130 case PATTERN_PER_MILLE:
2131 c = symbols.getPerMill();
2132 field = -1;
2133 fieldID = Field.PERMILLE;
2134 break;
2135 case PATTERN_MINUS:
2136 c = symbols.getMinusSign();
2137 field = -1;
2138 fieldID = Field.SIGN;
2139 break;
2140 }
2141 if (fieldID != null) {
2142 if (positions == null) {
2143 positions = new ArrayList(2);
2144 }
2145 FieldPosition fp = new FieldPosition(fieldID, field);
2146 fp.setBeginIndex(stringIndex);
2147 fp.setEndIndex(stringIndex + 1);
2148 positions.add(fp);
2149 }
2150 }
2151 stringIndex++;
2152 }
2153 if (positions != null) {
2154 return (FieldPosition[]) positions
2155 .toArray(EmptyFieldPositionArray);
2156 }
2157 return EmptyFieldPositionArray;
2158 }
2159
2160 /**
2161 * Appends an affix pattern to the given StringBuffer, quoting special
2162 * characters as needed. Uses the internal affix pattern, if that exists,
2163 * or the literal affix, if the internal affix pattern is null. The
2164 * appended string will generate the same affix pattern (or literal affix)
2165 * when passed to toPattern().
2166 *
2167 * @param buffer the affix string is appended to this
2168 * @param affixPattern a pattern such as posPrefixPattern; may be null
2169 * @param expAffix a corresponding expanded affix, such as positivePrefix.
2170 * Ignored unless affixPattern is null. If affixPattern is null, then
2171 * expAffix is appended as a literal affix.
2172 * @param localized true if the appended pattern should contain localized
2173 * pattern characters; otherwise, non-localized pattern chars are appended
2174 */
2175 private void appendAffix(StringBuffer buffer, String affixPattern,
2176 String expAffix, boolean localized) {
2177 if (affixPattern == null) {
2178 appendAffix(buffer, expAffix, localized);
2179 } else {
2180 int i;
2181 for (int pos = 0; pos < affixPattern.length(); pos = i) {
2182 i = affixPattern.indexOf(QUOTE, pos);
2183 if (i < 0) {
2184 appendAffix(buffer, affixPattern.substring(pos),
2185 localized);
2186 break;
2187 }
2188 if (i > pos) {
2189 appendAffix(buffer, affixPattern.substring(pos, i),
2190 localized);
2191 }
2192 char c = affixPattern.charAt(++i);
2193 ++i;
2194 if (c == QUOTE) {
2195 buffer.append(c);
2196 // Fall through and append another QUOTE below
2197 } else if (c == CURRENCY_SIGN
2198 && i < affixPattern.length()
2199 && affixPattern.charAt(i) == CURRENCY_SIGN) {
2200 ++i;
2201 buffer.append(c);
2202 // Fall through and append another CURRENCY_SIGN below
2203 } else if (localized) {
2204 switch (c) {
2205 case PATTERN_PERCENT:
2206 c = symbols.getPercent();
2207 break;
2208 case PATTERN_PER_MILLE:
2209 c = symbols.getPerMill();
2210 break;
2211 case PATTERN_MINUS:
2212 c = symbols.getMinusSign();
2213 break;
2214 }
2215 }
2216 buffer.append(c);
2217 }
2218 }
2219 }
2220
2221 /**
2222 * Append an affix to the given StringBuffer, using quotes if
2223 * there are special characters. Single quotes themselves must be
2224 * escaped in either case.
2225 */
2226 private void appendAffix(StringBuffer buffer, String affix,
2227 boolean localized) {
2228 boolean needQuote;
2229 if (localized) {
2230 needQuote = affix.indexOf(symbols.getZeroDigit()) >= 0
2231 || affix.indexOf(symbols.getGroupingSeparator()) >= 0
2232 || affix.indexOf(symbols.getDecimalSeparator()) >= 0
2233 || affix.indexOf(symbols.getPercent()) >= 0
2234 || affix.indexOf(symbols.getPerMill()) >= 0
2235 || affix.indexOf(symbols.getDigit()) >= 0
2236 || affix.indexOf(symbols.getPatternSeparator()) >= 0
2237 || affix.indexOf(symbols.getMinusSign()) >= 0
2238 || affix.indexOf(CURRENCY_SIGN) >= 0;
2239 } else {
2240 needQuote = affix.indexOf(PATTERN_ZERO_DIGIT) >= 0
2241 || affix.indexOf(PATTERN_GROUPING_SEPARATOR) >= 0
2242 || affix.indexOf(PATTERN_DECIMAL_SEPARATOR) >= 0
2243 || affix.indexOf(PATTERN_PERCENT) >= 0
2244 || affix.indexOf(PATTERN_PER_MILLE) >= 0
2245 || affix.indexOf(PATTERN_DIGIT) >= 0
2246 || affix.indexOf(PATTERN_SEPARATOR) >= 0
2247 || affix.indexOf(PATTERN_MINUS) >= 0
2248 || affix.indexOf(CURRENCY_SIGN) >= 0;
2249 }
2250 if (needQuote)
2251 buffer.append('\'');
2252 if (affix.indexOf('\'') < 0)
2253 buffer.append(affix);
2254 else {
2255 for (int j = 0; j < affix.length(); ++j) {
2256 char c = affix.charAt(j);
2257 buffer.append(c);
2258 if (c == '\'')
2259 buffer.append(c);
2260 }
2261 }
2262 if (needQuote)
2263 buffer.append('\'');
2264 }
2265
2266 /**
2267 * Does the real work of generating a pattern. */
2268 private String toPattern(boolean localized) {
2269 StringBuffer result = new StringBuffer();
2270 for (int j = 1; j >= 0; --j) {
2271 if (j == 1)
2272 appendAffix(result, posPrefixPattern, positivePrefix,
2273 localized);
2274 else
2275 appendAffix(result, negPrefixPattern, negativePrefix,
2276 localized);
2277 int i;
2278 int digitCount = useExponentialNotation ? getMaximumIntegerDigits()
2279 : Math.max(groupingSize, getMinimumIntegerDigits()) + 1;
2280 for (i = digitCount; i > 0; --i) {
2281 if (i != digitCount && isGroupingUsed()
2282 && groupingSize != 0 && i % groupingSize == 0) {
2283 result.append(localized ? symbols
2284 .getGroupingSeparator()
2285 : PATTERN_GROUPING_SEPARATOR);
2286 }
2287 result
2288 .append(i <= getMinimumIntegerDigits() ? (localized ? symbols
2289 .getZeroDigit()
2290 : PATTERN_ZERO_DIGIT)
2291 : (localized ? symbols.getDigit()
2292 : PATTERN_DIGIT));
2293 }
2294 if (getMaximumFractionDigits() > 0
2295 || decimalSeparatorAlwaysShown)
2296 result.append(localized ? symbols.getDecimalSeparator()
2297 : PATTERN_DECIMAL_SEPARATOR);
2298 for (i = 0; i < getMaximumFractionDigits(); ++i) {
2299 if (i < getMinimumFractionDigits()) {
2300 result.append(localized ? symbols.getZeroDigit()
2301 : PATTERN_ZERO_DIGIT);
2302 } else {
2303 result.append(localized ? symbols.getDigit()
2304 : PATTERN_DIGIT);
2305 }
2306 }
2307 if (useExponentialNotation) {
2308 result.append(localized ? symbols
2309 .getExponentSeparator() : PATTERN_EXPONENT);
2310 for (i = 0; i < minExponentDigits; ++i)
2311 result.append(localized ? symbols.getZeroDigit()
2312 : PATTERN_ZERO_DIGIT);
2313 }
2314 if (j == 1) {
2315 appendAffix(result, posSuffixPattern, positiveSuffix,
2316 localized);
2317 if ((negSuffixPattern == posSuffixPattern && // n == p == null
2318 negativeSuffix.equals(positiveSuffix))
2319 || (negSuffixPattern != null && negSuffixPattern
2320 .equals(posSuffixPattern))) {
2321 if ((negPrefixPattern != null
2322 && posPrefixPattern != null && negPrefixPattern
2323 .equals("'-" + posPrefixPattern))
2324 || (negPrefixPattern == posPrefixPattern && // n == p == null
2325 negativePrefix.equals(symbols
2326 .getMinusSign()
2327 + positivePrefix)))
2328 break;
2329 }
2330 result.append(localized ? symbols.getPatternSeparator()
2331 : PATTERN_SEPARATOR);
2332 } else
2333 appendAffix(result, negSuffixPattern, negativeSuffix,
2334 localized);
2335 }
2336 return result.toString();
2337 }
2338
2339 /**
2340 * Apply the given pattern to this Format object. A pattern is a
2341 * short-hand specification for the various formatting properties.
2342 * These properties can also be changed individually through the
2343 * various setter methods.
2344 * <p>
2345 * There is no limit to integer digits set
2346 * by this routine, since that is the typical end-user desire;
2347 * use setMaximumInteger if you want to set a real value.
2348 * For negative numbers, use a second pattern, separated by a semicolon
2349 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2350 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2351 * a maximum of 2 fraction digits.
2352 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2353 * parentheses.
2354 * <p>In negative patterns, the minimum and maximum counts are ignored;
2355 * these are presumed to be set in the positive pattern.
2356 *
2357 * @exception NullPointerException if <code>pattern</code> is null
2358 * @exception IllegalArgumentException if the given pattern is invalid.
2359 */
2360 public void applyPattern(String pattern) {
2361 applyPattern(pattern, false);
2362 }
2363
2364 /**
2365 * Apply the given pattern to this Format object. The pattern
2366 * is assumed to be in a localized notation. A pattern is a
2367 * short-hand specification for the various formatting properties.
2368 * These properties can also be changed individually through the
2369 * various setter methods.
2370 * <p>
2371 * There is no limit to integer digits set
2372 * by this routine, since that is the typical end-user desire;
2373 * use setMaximumInteger if you want to set a real value.
2374 * For negative numbers, use a second pattern, separated by a semicolon
2375 * <P>Example <code>"#,#00.0#"</code> -> 1,234.56
2376 * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
2377 * a maximum of 2 fraction digits.
2378 * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
2379 * parentheses.
2380 * <p>In negative patterns, the minimum and maximum counts are ignored;
2381 * these are presumed to be set in the positive pattern.
2382 *
2383 * @exception NullPointerException if <code>pattern</code> is null
2384 * @exception IllegalArgumentException if the given pattern is invalid.
2385 */
2386 public void applyLocalizedPattern(String pattern) {
2387 applyPattern(pattern, true);
2388 }
2389
2390 /**
2391 * Does the real work of applying a pattern.
2392 */
2393 private void applyPattern(String pattern, boolean localized) {
2394 char zeroDigit = PATTERN_ZERO_DIGIT;
2395 char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
2396 char decimalSeparator = PATTERN_DECIMAL_SEPARATOR;
2397 char percent = PATTERN_PERCENT;
2398 char perMill = PATTERN_PER_MILLE;
2399 char digit = PATTERN_DIGIT;
2400 char separator = PATTERN_SEPARATOR;
2401 String exponent = PATTERN_EXPONENT;
2402 char minus = PATTERN_MINUS;
2403 if (localized) {
2404 zeroDigit = symbols.getZeroDigit();
2405 groupingSeparator = symbols.getGroupingSeparator();
2406 decimalSeparator = symbols.getDecimalSeparator();
2407 percent = symbols.getPercent();
2408 perMill = symbols.getPerMill();
2409 digit = symbols.getDigit();
2410 separator = symbols.getPatternSeparator();
2411 exponent = symbols.getExponentSeparator();
2412 minus = symbols.getMinusSign();
2413 }
2414 boolean gotNegative = false;
2415 decimalSeparatorAlwaysShown = false;
2416 isCurrencyFormat = false;
2417 useExponentialNotation = false;
2418
2419 // Two variables are used to record the subrange of the pattern
2420 // occupied by phase 1. This is used during the processing of the
2421 // second pattern (the one representing negative numbers) to ensure
2422 // that no deviation exists in phase 1 between the two patterns.
2423 int phaseOneStart = 0;
2424 int phaseOneLength = 0;
2425
2426 int start = 0;
2427 for (int j = 1; j >= 0 && start < pattern.length(); --j) {
2428 boolean inQuote = false;
2429 StringBuffer prefix = new StringBuffer();
2430 StringBuffer suffix = new StringBuffer();
2431 int decimalPos = -1;
2432 int multiplier = 1;
2433 int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
2434 byte groupingCount = -1;
2435
2436 // The phase ranges from 0 to 2. Phase 0 is the prefix. Phase 1 is
2437 // the section of the pattern with digits, decimal separator,
2438 // grouping characters. Phase 2 is the suffix. In phases 0 and 2,
2439 // percent, per mille, and currency symbols are recognized and
2440 // translated. The separation of the characters into phases is
2441 // strictly enforced; if phase 1 characters are to appear in the
2442 // suffix, for example, they must be quoted.
2443 int phase = 0;
2444
2445 // The affix is either the prefix or the suffix.
2446 StringBuffer affix = prefix;
2447
2448 for (int pos = start; pos < pattern.length(); ++pos) {
2449 char ch = pattern.charAt(pos);
2450 switch (phase) {
2451 case 0:
2452 case 2:
2453 // Process the prefix / suffix characters
2454 if (inQuote) {
2455 // A quote within quotes indicates either the closing
2456 // quote or two quotes, which is a quote literal. That
2457 // is, we have the second quote in 'do' or 'don''t'.
2458 if (ch == QUOTE) {
2459 if ((pos + 1) < pattern.length()
2460 && pattern.charAt(pos + 1) == QUOTE) {
2461 ++pos;
2462 affix.append("''"); // 'don''t'
2463 } else {
2464 inQuote = false; // 'do'
2465 }
2466 continue;
2467 }
2468 } else {
2469 // Process unquoted characters seen in prefix or suffix
2470 // phase.
2471 if (ch == digit || ch == zeroDigit
2472 || ch == groupingSeparator
2473 || ch == decimalSeparator) {
2474 phase = 1;
2475 if (j == 1) {
2476 phaseOneStart = pos;
2477 }
2478 --pos; // Reprocess this character
2479 continue;
2480 } else if (ch == CURRENCY_SIGN) {
2481 // Use lookahead to determine if the currency sign
2482 // is doubled or not.
2483 boolean doubled = (pos + 1) < pattern
2484 .length()
2485 && pattern.charAt(pos + 1) == CURRENCY_SIGN;
2486 if (doubled) { // Skip over the doubled character
2487 ++pos;
2488 }
2489 isCurrencyFormat = true;
2490 affix.append(doubled ? "'\u00A4\u00A4"
2491 : "'\u00A4");
2492 continue;
2493 } else if (ch == QUOTE) {
2494 // A quote outside quotes indicates either the
2495 // opening quote or two quotes, which is a quote
2496 // literal. That is, we have the first quote in 'do'
2497 // or o''clock.
2498 if (ch == QUOTE) {
2499 if ((pos + 1) < pattern.length()
2500 && pattern.charAt(pos + 1) == QUOTE) {
2501 ++pos;
2502 affix.append("''"); // o''clock
2503 } else {
2504 inQuote = true; // 'do'
2505 }
2506 continue;
2507 }
2508 } else if (ch == separator) {
2509 // Don't allow separators before we see digit
2510 // characters of phase 1, and don't allow separators
2511 // in the second pattern (j == 0).
2512 if (phase == 0 || j == 0) {
2513 throw new IllegalArgumentException(
2514 "Unquoted special character '"
2515 + ch
2516 + "' in pattern \""
2517 + pattern + '"');
2518 }
2519 start = pos + 1;
2520 pos = pattern.length();
2521 continue;
2522 }
2523
2524 // Next handle characters which are appended directly.
2525 else if (ch == percent) {
2526 if (multiplier != 1) {
2527 throw new IllegalArgumentException(
2528 "Too many percent/per mille characters in pattern \""
2529 + pattern + '"');
2530 }
2531 multiplier = 100;
2532 affix.append("'%");
2533 continue;
2534 } else if (ch == perMill) {
2535 if (multiplier != 1) {
2536 throw new IllegalArgumentException(
2537 "Too many percent/per mille characters in pattern \""
2538 + pattern + '"');
2539 }
2540 multiplier = 1000;
2541 affix.append("'\u2030");
2542 continue;
2543 } else if (ch == minus) {
2544 affix.append("'-");
2545 continue;
2546 }
2547 }
2548 // Note that if we are within quotes, or if this is an
2549 // unquoted, non-special character, then we usually fall
2550 // through to here.
2551 affix.append(ch);
2552 break;
2553
2554 case 1:
2555 // Phase one must be identical in the two sub-patterns. We
2556 // enforce this by doing a direct comparison. While
2557 // processing the first sub-pattern, we just record its
2558 // length. While processing the second, we compare
2559 // characters.
2560 if (j == 1) {
2561 ++phaseOneLength;
2562 } else {
2563 if (--phaseOneLength == 0) {
2564 phase = 2;
2565 affix = suffix;
2566 }
2567 continue;
2568 }
2569
2570 // Process the digits, decimal, and grouping characters. We
2571 // record five pieces of information. We expect the digits
2572 // to occur in the pattern ####0000.####, and we record the
2573 // number of left digits, zero (central) digits, and right
2574 // digits. The position of the last grouping character is
2575 // recorded (should be somewhere within the first two blocks
2576 // of characters), as is the position of the decimal point,
2577 // if any (should be in the zero digits). If there is no
2578 // decimal point, then there should be no right digits.
2579 if (ch == digit) {
2580 if (zeroDigitCount > 0) {
2581 ++digitRightCount;
2582 } else {
2583 ++digitLeftCount;
2584 }
2585 if (groupingCount >= 0 && decimalPos < 0) {
2586 ++groupingCount;
2587 }
2588 } else if (ch == zeroDigit) {
2589 if (digitRightCount > 0) {
2590 throw new IllegalArgumentException(
2591 "Unexpected '0' in pattern \""
2592 + pattern + '"');
2593 }
2594 ++zeroDigitCount;
2595 if (groupingCount >= 0 && decimalPos < 0) {
2596 ++groupingCount;
2597 }
2598 } else if (ch == groupingSeparator) {
2599 groupingCount = 0;
2600 } else if (ch == decimalSeparator) {
2601 if (decimalPos >= 0) {
2602 throw new IllegalArgumentException(
2603 "Multiple decimal separators in pattern \""
2604 + pattern + '"');
2605 }
2606 decimalPos = digitLeftCount + zeroDigitCount
2607 + digitRightCount;
2608 } else if (pattern.regionMatches(pos, exponent, 0,
2609 exponent.length())) {
2610 if (useExponentialNotation) {
2611 throw new IllegalArgumentException(
2612 "Multiple exponential "
2613 + "symbols in pattern \""
2614 + pattern + '"');
2615 }
2616 useExponentialNotation = true;
2617 minExponentDigits = 0;
2618
2619 // Use lookahead to parse out the exponential part
2620 // of the pattern, then jump into phase 2.
2621 pos = pos + exponent.length();
2622 while (pos < pattern.length()
2623 && pattern.charAt(pos) == zeroDigit) {
2624 ++minExponentDigits;
2625 ++phaseOneLength;
2626 ++pos;
2627 }
2628
2629 if ((digitLeftCount + zeroDigitCount) < 1
2630 || minExponentDigits < 1) {
2631 throw new IllegalArgumentException(
2632 "Malformed exponential "
2633 + "pattern \"" + pattern
2634 + '"');
2635 }
2636
2637 // Transition to phase 2
2638 phase = 2;
2639 affix = suffix;
2640 --pos;
2641 continue;
2642 } else {
2643 phase = 2;
2644 affix = suffix;
2645 --pos;
2646 --phaseOneLength;
2647 continue;
2648 }
2649 break;
2650 }
2651 }
2652
2653 // Handle patterns with no '0' pattern character. These patterns
2654 // are legal, but must be interpreted. "##.###" -> "#0.###".
2655 // ".###" -> ".0##".
2656 /* We allow patterns of the form "####" to produce a zeroDigitCount
2657 * of zero (got that?); although this seems like it might make it
2658 * possible for format() to produce empty strings, format() checks
2659 * for this condition and outputs a zero digit in this situation.
2660 * Having a zeroDigitCount of zero yields a minimum integer digits
2661 * of zero, which allows proper round-trip patterns. That is, we
2662 * don't want "#" to become "#0" when toPattern() is called (even
2663 * though that's what it really is, semantically).
2664 */
2665 if (zeroDigitCount == 0 && digitLeftCount > 0
2666 && decimalPos >= 0) {
2667 // Handle "###.###" and "###." and ".###"
2668 int n = decimalPos;
2669 if (n == 0) { // Handle ".###"
2670 ++n;
2671 }
2672 digitRightCount = digitLeftCount - n;
2673 digitLeftCount = n - 1;
2674 zeroDigitCount = 1;
2675 }
2676
2677 // Do syntax checking on the digits.
2678 if ((decimalPos < 0 && digitRightCount > 0)
2679 || (decimalPos >= 0 && (decimalPos < digitLeftCount || decimalPos > (digitLeftCount + zeroDigitCount)))
2680 || groupingCount == 0 || inQuote) {
2681 throw new IllegalArgumentException(
2682 "Malformed pattern \"" + pattern + '"');
2683 }
2684
2685 if (j == 1) {
2686 posPrefixPattern = prefix.toString();
2687 posSuffixPattern = suffix.toString();
2688 negPrefixPattern = posPrefixPattern; // assume these for now
2689 negSuffixPattern = posSuffixPattern;
2690 int digitTotalCount = digitLeftCount + zeroDigitCount
2691 + digitRightCount;
2692 /* The effectiveDecimalPos is the position the decimal is at or
2693 * would be at if there is no decimal. Note that if decimalPos<0,
2694 * then digitTotalCount == digitLeftCount + zeroDigitCount.
2695 */
2696 int effectiveDecimalPos = decimalPos >= 0 ? decimalPos
2697 : digitTotalCount;
2698 setMinimumIntegerDigits(effectiveDecimalPos
2699 - digitLeftCount);
2700 setMaximumIntegerDigits(useExponentialNotation ? digitLeftCount
2701 + getMinimumIntegerDigits()
2702 : MAXIMUM_INTEGER_DIGITS);
2703 setMaximumFractionDigits(decimalPos >= 0 ? (digitTotalCount - decimalPos)
2704 : 0);
2705 setMinimumFractionDigits(decimalPos >= 0 ? (digitLeftCount
2706 + zeroDigitCount - decimalPos)
2707 : 0);
2708 setGroupingUsed(groupingCount > 0);
2709 this .groupingSize = (groupingCount > 0) ? groupingCount
2710 : 0;
2711 this .multiplier = multiplier;
2712 setDecimalSeparatorAlwaysShown(decimalPos == 0
2713 || decimalPos == digitTotalCount);
2714 } else {
2715 negPrefixPattern = prefix.toString();
2716 negSuffixPattern = suffix.toString();
2717 gotNegative = true;
2718 }
2719 }
2720
2721 if (pattern.length() == 0) {
2722 posPrefixPattern = posSuffixPattern = "";
2723 setMinimumIntegerDigits(0);
2724 setMaximumIntegerDigits(MAXIMUM_INTEGER_DIGITS);
2725 setMinimumFractionDigits(0);
2726 setMaximumFractionDigits(MAXIMUM_FRACTION_DIGITS);
2727 }
2728
2729 // If there was no negative pattern, or if the negative pattern is
2730 // identical to the positive pattern, then prepend the minus sign to
2731 // the positive pattern to form the negative pattern.
2732 if (!gotNegative
2733 || (negPrefixPattern.equals(posPrefixPattern) && negSuffixPattern
2734 .equals(posSuffixPattern))) {
2735 negSuffixPattern = posSuffixPattern;
2736 negPrefixPattern = "'-" + posPrefixPattern;
2737 }
2738
2739 expandAffixes();
2740 }
2741
2742 /**
2743 * Sets the maximum number of digits allowed in the integer portion of a
2744 * number.
2745 * For formatting numbers other than <code>BigInteger</code> and
2746 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2747 * 309 is used. Negative input values are replaced with 0.
2748 * @see NumberFormat#setMaximumIntegerDigits
2749 */
2750 public void setMaximumIntegerDigits(int newValue) {
2751 maximumIntegerDigits = Math.min(Math.max(0, newValue),
2752 MAXIMUM_INTEGER_DIGITS);
2753 super
2754 .setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS
2755 : maximumIntegerDigits);
2756 if (minimumIntegerDigits > maximumIntegerDigits) {
2757 minimumIntegerDigits = maximumIntegerDigits;
2758 super
2759 .setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS
2760 : minimumIntegerDigits);
2761 }
2762 }
2763
2764 /**
2765 * Sets the minimum number of digits allowed in the integer portion of a
2766 * number.
2767 * For formatting numbers other than <code>BigInteger</code> and
2768 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2769 * 309 is used. Negative input values are replaced with 0.
2770 * @see NumberFormat#setMinimumIntegerDigits
2771 */
2772 public void setMinimumIntegerDigits(int newValue) {
2773 minimumIntegerDigits = Math.min(Math.max(0, newValue),
2774 MAXIMUM_INTEGER_DIGITS);
2775 super
2776 .setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS
2777 : minimumIntegerDigits);
2778 if (minimumIntegerDigits > maximumIntegerDigits) {
2779 maximumIntegerDigits = minimumIntegerDigits;
2780 super
2781 .setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ? DOUBLE_INTEGER_DIGITS
2782 : maximumIntegerDigits);
2783 }
2784 }
2785
2786 /**
2787 * Sets the maximum number of digits allowed in the fraction portion of a
2788 * number.
2789 * For formatting numbers other than <code>BigInteger</code> and
2790 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2791 * 340 is used. Negative input values are replaced with 0.
2792 * @see NumberFormat#setMaximumFractionDigits
2793 */
2794 public void setMaximumFractionDigits(int newValue) {
2795 maximumFractionDigits = Math.min(Math.max(0, newValue),
2796 MAXIMUM_FRACTION_DIGITS);
2797 super
2798 .setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS
2799 : maximumFractionDigits);
2800 if (minimumFractionDigits > maximumFractionDigits) {
2801 minimumFractionDigits = maximumFractionDigits;
2802 super
2803 .setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS
2804 : minimumFractionDigits);
2805 }
2806 }
2807
2808 /**
2809 * Sets the minimum number of digits allowed in the fraction portion of a
2810 * number.
2811 * For formatting numbers other than <code>BigInteger</code> and
2812 * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
2813 * 340 is used. Negative input values are replaced with 0.
2814 * @see NumberFormat#setMinimumFractionDigits
2815 */
2816 public void setMinimumFractionDigits(int newValue) {
2817 minimumFractionDigits = Math.min(Math.max(0, newValue),
2818 MAXIMUM_FRACTION_DIGITS);
2819 super
2820 .setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS
2821 : minimumFractionDigits);
2822 if (minimumFractionDigits > maximumFractionDigits) {
2823 maximumFractionDigits = minimumFractionDigits;
2824 super
2825 .setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ? DOUBLE_FRACTION_DIGITS
2826 : maximumFractionDigits);
2827 }
2828 }
2829
2830 /**
2831 * Gets the maximum number of digits allowed in the integer portion of a
2832 * number.
2833 * For formatting numbers other than <code>BigInteger</code> and
2834 * <code>BigDecimal</code> objects, the lower of the return value and
2835 * 309 is used.
2836 * @see #setMaximumIntegerDigits
2837 */
2838 public int getMaximumIntegerDigits() {
2839 return maximumIntegerDigits;
2840 }
2841
2842 /**
2843 * Gets the minimum number of digits allowed in the integer portion of a
2844 * number.
2845 * For formatting numbers other than <code>BigInteger</code> and
2846 * <code>BigDecimal</code> objects, the lower of the return value and
2847 * 309 is used.
2848 * @see #setMinimumIntegerDigits
2849 */
2850 public int getMinimumIntegerDigits() {
2851 return minimumIntegerDigits;
2852 }
2853
2854 /**
2855 * Gets the maximum number of digits allowed in the fraction portion of a
2856 * number.
2857 * For formatting numbers other than <code>BigInteger</code> and
2858 * <code>BigDecimal</code> objects, the lower of the return value and
2859 * 340 is used.
2860 * @see #setMaximumFractionDigits
2861 */
2862 public int getMaximumFractionDigits() {
2863 return maximumFractionDigits;
2864 }
2865
2866 /**
2867 * Gets the minimum number of digits allowed in the fraction portion of a
2868 * number.
2869 * For formatting numbers other than <code>BigInteger</code> and
2870 * <code>BigDecimal</code> objects, the lower of the return value and
2871 * 340 is used.
2872 * @see #setMinimumFractionDigits
2873 */
2874 public int getMinimumFractionDigits() {
2875 return minimumFractionDigits;
2876 }
2877
2878 /**
2879 * Gets the currency used by this decimal format when formatting
2880 * currency values.
2881 * The currency is obtained by calling
2882 * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
2883 * on this number format's symbols.
2884 *
2885 * @return the currency used by this decimal format, or <code>null</code>
2886 * @since 1.4
2887 */
2888 public Currency getCurrency() {
2889 return symbols.getCurrency();
2890 }
2891
2892 /**
2893 * Sets the currency used by this number format when formatting
2894 * currency values. This does not update the minimum or maximum
2895 * number of fraction digits used by the number format.
2896 * The currency is set by calling
2897 * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
2898 * on this number format's symbols.
2899 *
2900 * @param currency the new currency to be used by this decimal format
2901 * @exception NullPointerException if <code>currency</code> is null
2902 * @since 1.4
2903 */
2904 public void setCurrency(Currency currency) {
2905 if (currency != symbols.getCurrency()) {
2906 symbols.setCurrency(currency);
2907 if (isCurrencyFormat) {
2908 expandAffixes();
2909 }
2910 }
2911 }
2912
2913 /**
2914 * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
2915 *
2916 * @return The <code>RoundingMode</code> used for this DecimalFormat.
2917 * @see #setRoundingMode(RoundingMode)
2918 * @since 1.6
2919 */
2920 public RoundingMode getRoundingMode() {
2921 return roundingMode;
2922 }
2923
2924 /**
2925 * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
2926 *
2927 * @param roundingMode The <code>RoundingMode</code> to be used
2928 * @see #getRoundingMode()
2929 * @exception NullPointerException if <code>roundingMode</code> is null.
2930 * @since 1.6
2931 */
2932 public void setRoundingMode(RoundingMode roundingMode) {
2933 if (roundingMode == null) {
2934 throw new NullPointerException();
2935 }
2936
2937 this .roundingMode = roundingMode;
2938 digitList.setRoundingMode(roundingMode);
2939 }
2940
2941 /**
2942 * Adjusts the minimum and maximum fraction digits to values that
2943 * are reasonable for the currency's default fraction digits.
2944 */
2945 void adjustForCurrencyDefaultFractionDigits() {
2946 Currency currency = symbols.getCurrency();
2947 if (currency == null) {
2948 try {
2949 currency = Currency.getInstance(symbols
2950 .getInternationalCurrencySymbol());
2951 } catch (IllegalArgumentException e) {
2952 }
2953 }
2954 if (currency != null) {
2955 int digits = currency.getDefaultFractionDigits();
2956 if (digits != -1) {
2957 int oldMinDigits = getMinimumFractionDigits();
2958 // Common patterns are "#.##", "#.00", "#".
2959 // Try to adjust all of them in a reasonable way.
2960 if (oldMinDigits == getMaximumFractionDigits()) {
2961 setMinimumFractionDigits(digits);
2962 setMaximumFractionDigits(digits);
2963 } else {
2964 setMinimumFractionDigits(Math.min(digits,
2965 oldMinDigits));
2966 setMaximumFractionDigits(digits);
2967 }
2968 }
2969 }
2970 }
2971
2972 /**
2973 * Reads the default serializable fields from the stream and performs
2974 * validations and adjustments for older serialized versions. The
2975 * validations and adjustments are:
2976 * <ol>
2977 * <li>
2978 * Verify that the superclass's digit count fields correctly reflect
2979 * the limits imposed on formatting numbers other than
2980 * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
2981 * limits are stored in the superclass for serialization compatibility
2982 * with older versions, while the limits for <code>BigInteger</code> and
2983 * <code>BigDecimal</code> objects are kept in this class.
2984 * If, in the superclass, the minimum or maximum integer digit count is
2985 * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
2986 * maximum fraction digit count is larger than
2987 * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
2988 * and this method throws an <code>InvalidObjectException</code>.
2989 * <li>
2990 * If <code>serialVersionOnStream</code> is less than 4, initialize
2991 * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
2992 * RoundingMode.HALF_EVEN}. This field is new with version 4.
2993 * <li>
2994 * If <code>serialVersionOnStream</code> is less than 3, then call
2995 * the setters for the minimum and maximum integer and fraction digits with
2996 * the values of the corresponding superclass getters to initialize the
2997 * fields in this class. The fields in this class are new with version 3.
2998 * <li>
2999 * If <code>serialVersionOnStream</code> is less than 1, indicating that
3000 * the stream was written by JDK 1.1, initialize
3001 * <code>useExponentialNotation</code>
3002 * to false, since it was not present in JDK 1.1.
3003 * <li>
3004 * Set <code>serialVersionOnStream</code> to the maximum allowed value so
3005 * that default serialization will work properly if this object is streamed
3006 * out again.
3007 * </ol>
3008 *
3009 * <p>Stream versions older than 2 will not have the affix pattern variables
3010 * <code>posPrefixPattern</code> etc. As a result, they will be initialized
3011 * to <code>null</code>, which means the affix strings will be taken as
3012 * literal values. This is exactly what we want, since that corresponds to
3013 * the pre-version-2 behavior.
3014 */
3015 private void readObject(ObjectInputStream stream)
3016 throws IOException, ClassNotFoundException {
3017 stream.defaultReadObject();
3018 digitList = new DigitList();
3019
3020 if (serialVersionOnStream < 4) {
3021 setRoundingMode(RoundingMode.HALF_EVEN);
3022 }
3023 // We only need to check the maximum counts because NumberFormat
3024 // .readObject has already ensured that the maximum is greater than the
3025 // minimum count.
3026 if (super .getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS
3027 || super .getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
3028 throw new InvalidObjectException("Digit count out of range");
3029 }
3030 if (serialVersionOnStream < 3) {
3031 setMaximumIntegerDigits(super .getMaximumIntegerDigits());
3032 setMinimumIntegerDigits(super .getMinimumIntegerDigits());
3033 setMaximumFractionDigits(super .getMaximumFractionDigits());
3034 setMinimumFractionDigits(super .getMinimumFractionDigits());
3035 }
3036 if (serialVersionOnStream < 1) {
3037 // Didn't have exponential fields
3038 useExponentialNotation = false;
3039 }
3040 serialVersionOnStream = currentSerialVersion;
3041 }
3042
3043 //----------------------------------------------------------------------
3044 // INSTANCE VARIABLES
3045 //----------------------------------------------------------------------
3046
3047 private transient DigitList digitList = new DigitList();
3048
3049 /**
3050 * The symbol used as a prefix when formatting positive numbers, e.g. "+".
3051 *
3052 * @serial
3053 * @see #getPositivePrefix
3054 */
3055 private String positivePrefix = "";
3056
3057 /**
3058 * The symbol used as a suffix when formatting positive numbers.
3059 * This is often an empty string.
3060 *
3061 * @serial
3062 * @see #getPositiveSuffix
3063 */
3064 private String positiveSuffix = "";
3065
3066 /**
3067 * The symbol used as a prefix when formatting negative numbers, e.g. "-".
3068 *
3069 * @serial
3070 * @see #getNegativePrefix
3071 */
3072 private String negativePrefix = "-";
3073
3074 /**
3075 * The symbol used as a suffix when formatting negative numbers.
3076 * This is often an empty string.
3077 *
3078 * @serial
3079 * @see #getNegativeSuffix
3080 */
3081 private String negativeSuffix = "";
3082
3083 /**
3084 * The prefix pattern for non-negative numbers. This variable corresponds
3085 * to <code>positivePrefix</code>.
3086 *
3087 * <p>This pattern is expanded by the method <code>expandAffix()</code> to
3088 * <code>positivePrefix</code> to update the latter to reflect changes in
3089 * <code>symbols</code>. If this variable is <code>null</code> then
3090 * <code>positivePrefix</code> is taken as a literal value that does not
3091 * change when <code>symbols</code> changes. This variable is always
3092 * <code>null</code> for <code>DecimalFormat</code> objects older than
3093 * stream version 2 restored from stream.
3094 *
3095 * @serial
3096 * @since 1.3
3097 */
3098 private String posPrefixPattern;
3099
3100 /**
3101 * The suffix pattern for non-negative numbers. This variable corresponds
3102 * to <code>positiveSuffix</code>. This variable is analogous to
3103 * <code>posPrefixPattern</code>; see that variable for further
3104 * documentation.
3105 *
3106 * @serial
3107 * @since 1.3
3108 */
3109 private String posSuffixPattern;
3110
3111 /**
3112 * The prefix pattern for negative numbers. This variable corresponds
3113 * to <code>negativePrefix</code>. This variable is analogous to
3114 * <code>posPrefixPattern</code>; see that variable for further
3115 * documentation.
3116 *
3117 * @serial
3118 * @since 1.3
3119 */
3120 private String negPrefixPattern;
3121
3122 /**
3123 * The suffix pattern for negative numbers. This variable corresponds
3124 * to <code>negativeSuffix</code>. This variable is analogous to
3125 * <code>posPrefixPattern</code>; see that variable for further
3126 * documentation.
3127 *
3128 * @serial
3129 * @since 1.3
3130 */
3131 private String negSuffixPattern;
3132
3133 /**
3134 * The multiplier for use in percent, per mille, etc.
3135 *
3136 * @serial
3137 * @see #getMultiplier
3138 */
3139 private int multiplier = 1;
3140
3141 /**
3142 * The number of digits between grouping separators in the integer
3143 * portion of a number. Must be greater than 0 if
3144 * <code>NumberFormat.groupingUsed</code> is true.
3145 *
3146 * @serial
3147 * @see #getGroupingSize
3148 * @see java.text.NumberFormat#isGroupingUsed
3149 */
3150 private byte groupingSize = 3; // invariant, > 0 if useThousands
3151
3152 /**
3153 * If true, forces the decimal separator to always appear in a formatted
3154 * number, even if the fractional part of the number is zero.
3155 *
3156 * @serial
3157 * @see #isDecimalSeparatorAlwaysShown
3158 */
3159 private boolean decimalSeparatorAlwaysShown = false;
3160
3161 /**
3162 * If true, parse returns BigDecimal wherever possible.
3163 *
3164 * @serial
3165 * @see #isParseBigDecimal
3166 * @since 1.5
3167 */
3168 private boolean parseBigDecimal = false;
3169
3170 /**
3171 * True if this object represents a currency format. This determines
3172 * whether the monetary decimal separator is used instead of the normal one.
3173 */
3174 private transient boolean isCurrencyFormat = false;
3175
3176 /**
3177 * The <code>DecimalFormatSymbols</code> object used by this format.
3178 * It contains the symbols used to format numbers, e.g. the grouping separator,
3179 * decimal separator, and so on.
3180 *
3181 * @serial
3182 * @see #setDecimalFormatSymbols
3183 * @see java.text.DecimalFormatSymbols
3184 */
3185 private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
3186
3187 /**
3188 * True to force the use of exponential (i.e. scientific) notation when formatting
3189 * numbers.
3190 *
3191 * @serial
3192 * @since 1.2
3193 */
3194 private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.2
3195
3196 /**
3197 * FieldPositions describing the positive prefix String. This is
3198 * lazily created. Use <code>getPositivePrefixFieldPositions</code>
3199 * when needed.
3200 */
3201 private transient FieldPosition[] positivePrefixFieldPositions;
3202
3203 /**
3204 * FieldPositions describing the positive suffix String. This is
3205 * lazily created. Use <code>getPositiveSuffixFieldPositions</code>
3206 * when needed.
3207 */
3208 private transient FieldPosition[] positiveSuffixFieldPositions;
3209
3210 /**
3211 * FieldPositions describing the negative prefix String. This is
3212 * lazily created. Use <code>getNegativePrefixFieldPositions</code>
3213 * when needed.
3214 */
3215 private transient FieldPosition[] negativePrefixFieldPositions;
3216
3217 /**
3218 * FieldPositions describing the negative suffix String. This is
3219 * lazily created. Use <code>getNegativeSuffixFieldPositions</code>
3220 * when needed.
3221 */
3222 private transient FieldPosition[] negativeSuffixFieldPositions;
3223
3224 /**
3225 * The minimum number of digits used to display the exponent when a number is
3226 * formatted in exponential notation. This field is ignored if
3227 * <code>useExponentialNotation</code> is not true.
3228 *
3229 * @serial
3230 * @since 1.2
3231 */
3232 private byte minExponentDigits; // Newly persistent in the Java 2 platform v.1.2
3233
3234 /**
3235 * The maximum number of digits allowed in the integer portion of a
3236 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3237 * <code>maximumIntegerDigits</code> must be greater than or equal to
3238 * <code>minimumIntegerDigits</code>.
3239 *
3240 * @serial
3241 * @see #getMaximumIntegerDigits
3242 * @since 1.5
3243 */
3244 private int maximumIntegerDigits = super .getMaximumIntegerDigits();
3245
3246 /**
3247 * The minimum number of digits allowed in the integer portion of a
3248 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3249 * <code>minimumIntegerDigits</code> must be less than or equal to
3250 * <code>maximumIntegerDigits</code>.
3251 *
3252 * @serial
3253 * @see #getMinimumIntegerDigits
3254 * @since 1.5
3255 */
3256 private int minimumIntegerDigits = super .getMinimumIntegerDigits();
3257
3258 /**
3259 * The maximum number of digits allowed in the fractional portion of a
3260 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3261 * <code>maximumFractionDigits</code> must be greater than or equal to
3262 * <code>minimumFractionDigits</code>.
3263 *
3264 * @serial
3265 * @see #getMaximumFractionDigits
3266 * @since 1.5
3267 */
3268 private int maximumFractionDigits = super
3269 .getMaximumFractionDigits();
3270
3271 /**
3272 * The minimum number of digits allowed in the fractional portion of a
3273 * <code>BigInteger</code> or <code>BigDecimal</code> number.
3274 * <code>minimumFractionDigits</code> must be less than or equal to
3275 * <code>maximumFractionDigits</code>.
3276 *
3277 * @serial
3278 * @see #getMinimumFractionDigits
3279 * @since 1.5
3280 */
3281 private int minimumFractionDigits = super
3282 .getMinimumFractionDigits();
3283
3284 /**
3285 * The {@link java.math.RoundingMode} used in this DecimalFormat.
3286 *
3287 * @serial
3288 * @since 1.6
3289 */
3290 private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
3291
3292 //----------------------------------------------------------------------
3293
3294 static final int currentSerialVersion = 4;
3295
3296 /**
3297 * The internal serial version which says which version was written.
3298 * Possible values are:
3299 * <ul>
3300 * <li><b>0</b> (default): versions before the Java 2 platform v1.2
3301 * <li><b>1</b>: version for 1.2, which includes the two new fields
3302 * <code>useExponentialNotation</code> and
3303 * <code>minExponentDigits</code>.
3304 * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
3305 * <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
3306 * <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
3307 * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
3308 * <code>maximumIntegerDigits</code>,
3309 * <code>minimumIntegerDigits</code>,
3310 * <code>maximumFractionDigits</code>,
3311 * <code>minimumFractionDigits</code>, and
3312 * <code>parseBigDecimal</code>.
3313 * <li><b>4</b>: version for 1.6 and later, which adds one new field:
3314 * <code>roundingMode</code>.
3315 * </ul>
3316 * @since 1.2
3317 * @serial
3318 */
3319 private int serialVersionOnStream = currentSerialVersion;
3320
3321 //----------------------------------------------------------------------
3322 // CONSTANTS
3323 //----------------------------------------------------------------------
3324
3325 // Constants for characters used in programmatic (unlocalized) patterns.
3326 private static final char PATTERN_ZERO_DIGIT = '0';
3327 private static final char PATTERN_GROUPING_SEPARATOR = ',';
3328 private static final char PATTERN_DECIMAL_SEPARATOR = '.';
3329 private static final char PATTERN_PER_MILLE = '\u2030';
3330 private static final char PATTERN_PERCENT = '%';
3331 private static final char PATTERN_DIGIT = '#';
3332 private static final char PATTERN_SEPARATOR = ';';
3333 private static final String PATTERN_EXPONENT = "E";
3334 private static final char PATTERN_MINUS = '-';
3335
3336 /**
3337 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
3338 * is used in patterns and substituted with either the currency symbol,
3339 * or if it is doubled, with the international currency symbol. If the
3340 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
3341 * replaced with the monetary decimal separator.
3342 *
3343 * The CURRENCY_SIGN is not localized.
3344 */
3345 private static final char CURRENCY_SIGN = '\u00A4';
3346
3347 private static final char QUOTE = '\'';
3348
3349 private static FieldPosition[] EmptyFieldPositionArray = new FieldPosition[0];
3350
3351 // Upper limit on integer and fraction digits for a Java double
3352 static final int DOUBLE_INTEGER_DIGITS = 309;
3353 static final int DOUBLE_FRACTION_DIGITS = 340;
3354
3355 // Upper limit on integer and fraction digits for BigDecimal and BigInteger
3356 static final int MAXIMUM_INTEGER_DIGITS = Integer.MAX_VALUE;
3357 static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
3358
3359 // Proclaim JDK 1.1 serial compatibility.
3360 static final long serialVersionUID = 864413376551465018L;
3361
3362 /**
3363 * Cache to hold the NumberPattern of a Locale.
3364 */
3365 private static Hashtable cachedLocaleData = new Hashtable(3);
3366 }
|