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