1. /*
  2. * @(#)NumberFormat.java 1.42 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * @(#)NumberFormat.java 1.42 01/11/29
  9. *
  10. * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  11. * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
  12. *
  13. * Portions copyright (c) 1996-1998 Sun Microsystems, Inc.
  14. * All Rights Reserved.
  15. *
  16. * The original version of this source code and documentation is copyrighted
  17. * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  18. * materials are provided under terms of a License Agreement between Taligent
  19. * and Sun. This technology is protected by multiple US and International
  20. * patents. This notice and attribution to Taligent may not be removed.
  21. * Taligent is a registered trademark of Taligent, Inc.
  22. *
  23. * Permission to use, copy, modify, and distribute this software
  24. * and its documentation for NON-COMMERCIAL purposes and without
  25. * fee is hereby granted provided that this copyright notice
  26. * appears in all copies. Please refer to the file "copyright.html"
  27. * for further important copyright and licensing information.
  28. *
  29. * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  30. * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  31. * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  32. * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  33. * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  34. * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  35. *
  36. */
  37. package java.text;
  38. import java.util.Locale;
  39. import java.util.ResourceBundle;
  40. import java.text.resources.*;
  41. import java.util.Hashtable;
  42. import java.math.BigInteger;
  43. import java.io.IOException;
  44. import java.io.ObjectInputStream;
  45. import java.io.ObjectOutputStream;
  46. /**
  47. * <code>NumberFormat</code> is the abstract base class for all number
  48. * formats. This class provides the interface for formatting and parsing
  49. * numbers. <code>NumberFormat</code> also provides methods for determining
  50. * which locales have number formats, and what their names are.
  51. *
  52. * <p>
  53. * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
  54. * Your code can be completely independent of the locale conventions for
  55. * decimal points, thousands-separators, or even the particular decimal
  56. * digits used, or whether the number format is even decimal.
  57. *
  58. * <p>
  59. * To format a number for the current Locale, use one of the factory
  60. * class methods:
  61. * <blockquote>
  62. * <pre>
  63. * myString = NumberFormat.getInstance().format(myNumber);
  64. * </pre>
  65. * </blockquote>
  66. * If you are formatting multiple numbers, it is
  67. * more efficient to get the format and use it multiple times so that
  68. * the system doesn't have to fetch the information about the local
  69. * language and country conventions multiple times.
  70. * <blockquote>
  71. * <pre>
  72. * NumberFormat nf = NumberFormat.getInstance();
  73. * for (int i = 0; i < a.length; ++i) {
  74. * output.println(nf.format(myNumber[i]) + "; ");
  75. * }
  76. * </pre>
  77. * </blockquote>
  78. * To format a number for a different Locale, specify it in the
  79. * call to <code>getInstance</code>.
  80. * <blockquote>
  81. * <pre>
  82. * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
  83. * </pre>
  84. * </blockquote>
  85. * You can also use a <code>NumberFormat</code> to parse numbers:
  86. * <blockquote>
  87. * <pre>
  88. * myNumber = nf.parse(myString);
  89. * </pre>
  90. * </blockquote>
  91. * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
  92. * normal number format. Use <code>getCurrencyInstance</code> to get the
  93. * currency number format. And use <code>getPercentInstance</code> to get a
  94. * format for displaying percentages. With this format, a fraction like
  95. * 0.53 is displayed as 53%.
  96. *
  97. * <p>
  98. * You can also control the display of numbers with such methods as
  99. * <code>setMinimumFractionDigits</code>.
  100. * If you want even more control over the format or parsing,
  101. * or want to give your users more control,
  102. * you can try casting the <code>NumberFormat</code> you get from the factory methods
  103. * to a <code>DecimalNumberFormat</code>. This will work for the vast majority
  104. * of locales; just remember to put it in a <code>try</code> block in case you
  105. * encounter an unusual one.
  106. *
  107. * <p>
  108. * NumberFormat and DecimalFormat are designed such that some controls
  109. * work for formatting and others work for parsing. The following is
  110. * the detailed description for each these control methods,
  111. * <p>
  112. * setParseIntegerOnly : only affects parsing, e.g.
  113. * if true, "3456.78" -> 3456 (and leaves the parse position just after index 6)
  114. * if false, "3456.78" -> 3456.78 (and leaves the parse position just after index 8)
  115. * This is independent of formatting. If you want to not show a decimal point
  116. * where there might be no digits after the decimal point, use
  117. * setDecimalSeparatorAlwaysShown.
  118. * <p>
  119. * setDecimalSeparatorAlwaysShown : only affects formatting, and only where
  120. * there might be no digits after the decimal point, such as with a pattern
  121. * like "#,##0.##", e.g.,
  122. * if true, 3456.00 -> "3,456."
  123. * if false, 3456.00 -> "3456"
  124. * This is independent of parsing. If you want parsing to stop at the decimal
  125. * point, use setParseIntegerOnly.
  126. *
  127. * <p>
  128. * You can also use forms of the <code>parse</code> and <code>format</code>
  129. * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
  130. * allow you to:
  131. * <ul>
  132. * <li> progressively parse through pieces of a string
  133. * <li> align the decimal point and other areas
  134. * </ul>
  135. * For example, you can align numbers in two ways:
  136. * <ol>
  137. * <li> If you are using a monospaced font with spacing for alignment,
  138. * you can pass the <code>FieldPosition</code> in your format call, with
  139. * <code>field</code> = <code>INTEGER_FIELD</code>. On output,
  140. * <code>getEndIndex</code> will be set to the offset between the
  141. * last character of the integer and the decimal. Add
  142. * (desiredSpaceCount - getEndIndex) spaces at the front of the string.
  143. *
  144. * <li> If you are using proportional fonts,
  145. * instead of padding with spaces, measure the width
  146. * of the string in pixels from the start to <code>getEndIndex</code>.
  147. * Then move the pen by
  148. * (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
  149. * It also works where there is no decimal, but possibly additional
  150. * characters at the end, e.g., with parentheses in negative
  151. * numbers: "(12)" for -12.
  152. * </ol>
  153. *
  154. * @see DecimalFormat
  155. * @see ChoiceFormat
  156. * @version 1.22 29 Jan 1997
  157. * @author Mark Davis
  158. * @author Helena Shih
  159. */
  160. public abstract class NumberFormat extends Format{
  161. /**
  162. * Field constant used to construct a FieldPosition object. Signifies that
  163. * the position of the integer part of a formatted number should be returned.
  164. * @see java.text.FieldPosition
  165. */
  166. public static final int INTEGER_FIELD = 0;
  167. /**
  168. * Field constant used to construct a FieldPosition object. Signifies that
  169. * the position of the fraction part of a formatted number should be returned.
  170. * @see java.text.FieldPosition
  171. */
  172. public static final int FRACTION_FIELD = 1;
  173. public final StringBuffer format(Object number,
  174. StringBuffer toAppendTo,
  175. FieldPosition pos)
  176. {
  177. if (number instanceof Long ||
  178. (number instanceof BigInteger && ((BigInteger)number).bitLength() < 64)) {
  179. return format(((Number)number).longValue(), toAppendTo, pos);
  180. }
  181. /* Here is the code that's required to get all the bits we can out of
  182. * BigDecimal into a long or double. In the interests of simplicity, we
  183. * don't use this code; we just convert BigDecimal values into doubles.
  184. * (Actually, to really do things right, you'd compare against both
  185. * Long.MIN_VALUE and Long.MAX_VALUE, since they differ in magnitude.)
  186. * Liu 6/98
  187. */
  188. // else if (number instanceof BigDecimal) {
  189. // BigDecimal bd = (BigDecimal)number;
  190. // try {
  191. // if (bd.setScale(0, BigDecimal.ROUND_UNNECESSARY).
  192. // abs().compareTo(new BigDecimal("9223372036854775807")) <= 0) {
  193. // return format(((Number)number).longValue(), toAppendTo, pos);
  194. // }
  195. // }
  196. // catch (ArithmeticException e) {}
  197. // return format(((Number)number).doubleValue(), toAppendTo, pos);
  198. // }
  199. else if (number instanceof Number) {
  200. return format(((Number)number).doubleValue(), toAppendTo, pos);
  201. }
  202. else {
  203. throw new IllegalArgumentException("Cannot format given Object as a Number");
  204. }
  205. }
  206. public final Object parseObject(String source,
  207. ParsePosition parsePosition)
  208. {
  209. return parse(source, parsePosition);
  210. }
  211. /**
  212. * Specialization of format.
  213. * @see java.text.Format#format
  214. */
  215. public final String format (double number) {
  216. return format(number,new StringBuffer(),
  217. new FieldPosition(0)).toString();
  218. }
  219. /**
  220. * Specialization of format.
  221. * @see java.text.Format#format
  222. */
  223. public final String format (long number) {
  224. return format(number,new StringBuffer(),
  225. new FieldPosition(0)).toString();
  226. }
  227. /**
  228. * Specialization of format.
  229. * @see java.text.Format#format
  230. */
  231. public abstract StringBuffer format(double number,
  232. StringBuffer toAppendTo,
  233. FieldPosition pos);
  234. /**
  235. * Specialization of format.
  236. * @see java.text.Format#format
  237. */
  238. public abstract StringBuffer format(long number,
  239. StringBuffer toAppendTo,
  240. FieldPosition pos);
  241. /**
  242. * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
  243. * Long.MAX_VALUE] and with no decimals), otherwise a Double.
  244. * If IntegerOnly is set, will stop at a decimal
  245. * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
  246. * after the 1).
  247. * Does not throw an exception; if no object can be parsed, index is
  248. * unchanged!
  249. * @see java.text.NumberFormat#isParseIntegerOnly
  250. * @see java.text.Format#parseObject
  251. */
  252. public abstract Number parse(String text, ParsePosition parsePosition);
  253. /**
  254. * Convenience method.
  255. *
  256. * @exception ParseException if the specified string is invalid.
  257. * @see #format
  258. */
  259. public Number parse(String text) throws ParseException {
  260. ParsePosition parsePosition = new ParsePosition(0);
  261. Number result = parse(text, parsePosition);
  262. if (parsePosition.index == 0) {
  263. throw new ParseException("Unparseable number: \"" + text + "\"",
  264. parsePosition.errorIndex);
  265. }
  266. return result;
  267. }
  268. /**
  269. * Returns true if this format will parse numbers as integers only.
  270. * For example in the English locale, with ParseIntegerOnly true, the
  271. * string "1234." would be parsed as the integer value 1234 and parsing
  272. * would stop at the "." character. Of course, the exact format accepted
  273. * by the parse operation is locale dependant and determined by sub-classes
  274. * of NumberFormat.
  275. */
  276. public boolean isParseIntegerOnly() {
  277. return parseIntegerOnly;
  278. }
  279. /**
  280. * Sets whether or not numbers should be parsed as integers only.
  281. * @see #isParseIntegerOnly
  282. */
  283. public void setParseIntegerOnly(boolean value) {
  284. parseIntegerOnly = value;
  285. }
  286. //============== Locale Stuff =====================
  287. /**
  288. * Returns the default number format for the current default locale.
  289. * The default format is one of the styles provided by the other
  290. * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
  291. * Exactly which one is locale dependant.
  292. */
  293. public final static NumberFormat getInstance() {
  294. return getInstance(Locale.getDefault(), NUMBERSTYLE);
  295. }
  296. /**
  297. * Returns the default number format for the specified locale.
  298. * The default format is one of the styles provided by the other
  299. * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
  300. * Exactly which one is locale dependant.
  301. */
  302. public static NumberFormat getInstance(Locale inLocale) {
  303. return getInstance(inLocale, NUMBERSTYLE);
  304. }
  305. /**
  306. * Returns a general-purpose number format for the current default locale.
  307. */
  308. public final static NumberFormat getNumberInstance() {
  309. return getInstance(Locale.getDefault(), NUMBERSTYLE);
  310. }
  311. /**
  312. * Returns a general-purpose number format for the specified locale.
  313. */
  314. public static NumberFormat getNumberInstance(Locale inLocale) {
  315. return getInstance(inLocale, NUMBERSTYLE);
  316. }
  317. /**
  318. * Returns a currency format for the current default locale.
  319. */
  320. public final static NumberFormat getCurrencyInstance() {
  321. return getInstance(Locale.getDefault(), CURRENCYSTYLE);
  322. }
  323. /**
  324. * Returns a currency format for the specified locale.
  325. */
  326. public static NumberFormat getCurrencyInstance(Locale inLocale) {
  327. return getInstance(inLocale, CURRENCYSTYLE);
  328. }
  329. /**
  330. * Returns a percentage format for the current default locale.
  331. */
  332. public final static NumberFormat getPercentInstance() {
  333. return getInstance(Locale.getDefault(), PERCENTSTYLE);
  334. }
  335. /**
  336. * Returns a percentage format for the specified locale.
  337. */
  338. public static NumberFormat getPercentInstance(Locale inLocale) {
  339. return getInstance(inLocale, PERCENTSTYLE);
  340. }
  341. /**
  342. * Returns a scientific format for the current default locale.
  343. */
  344. /*public*/ final static NumberFormat getScientificInstance() {
  345. return getInstance(Locale.getDefault(), SCIENTIFICSTYLE);
  346. }
  347. /**
  348. * Returns a scientific format for the specified locale.
  349. */
  350. /*public*/ static NumberFormat getScientificInstance(Locale inLocale) {
  351. return getInstance(inLocale, SCIENTIFICSTYLE);
  352. }
  353. /**
  354. * Get the set of Locales for which NumberFormats are installed
  355. * @return available locales
  356. */
  357. public static Locale[] getAvailableLocales() {
  358. return LocaleData.getAvailableLocales("NumberPatterns");
  359. }
  360. /**
  361. * Overrides hashCode
  362. */
  363. public int hashCode() {
  364. return maximumIntegerDigits * 37 + maxFractionDigits;
  365. // just enough fields for a reasonable distribution
  366. }
  367. /**
  368. * Overrides equals
  369. */
  370. public boolean equals(Object obj) {
  371. if (obj == null) return false;
  372. if (this == obj)
  373. return true;
  374. if (getClass() != obj.getClass())
  375. return false;
  376. NumberFormat other = (NumberFormat) obj;
  377. return (maximumIntegerDigits == other.maximumIntegerDigits
  378. && minimumIntegerDigits == other.minimumIntegerDigits
  379. && maximumFractionDigits == other.maximumFractionDigits
  380. && minimumFractionDigits == other.minimumFractionDigits
  381. && groupingUsed == other.groupingUsed
  382. && parseIntegerOnly == other.parseIntegerOnly);
  383. }
  384. /**
  385. * Overrides Cloneable
  386. */
  387. public Object clone()
  388. {
  389. NumberFormat other = (NumberFormat) super.clone();
  390. return other;
  391. }
  392. /**
  393. * Returns true if grouping is used in this format. For example, in the
  394. * English locale, with grouping on, the number 1234567 might be formatted
  395. * as "1,234,567". The grouping separator as well as the size of each group
  396. * is locale dependant and is determined by sub-classes of NumberFormat.
  397. * @see #setGroupingUsed
  398. */
  399. public boolean isGroupingUsed() {
  400. return groupingUsed;
  401. }
  402. /**
  403. * Set whether or not grouping will be used in this format.
  404. * @see #isGroupingUsed
  405. */
  406. public void setGroupingUsed(boolean newValue) {
  407. groupingUsed = newValue;
  408. }
  409. /**
  410. * Returns the maximum number of digits allowed in the integer portion of a
  411. * number.
  412. * @see #setMaximumIntegerDigits
  413. */
  414. public int getMaximumIntegerDigits() {
  415. return maximumIntegerDigits;
  416. }
  417. /**
  418. * Sets the maximum number of digits allowed in the integer portion of a
  419. * number. maximumIntegerDigits must be >= minimumIntegerDigits. If the
  420. * new value for maximumIntegerDigits is less than the current value
  421. * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
  422. * the new value.
  423. * @param newValue the maximum number of integer digits to be shown; if
  424. * less than zero, then zero is used. The concrete subclass may enforce an
  425. * upper limit to this value appropriate to the numeric type being formatted.
  426. * @see #getMaximumIntegerDigits
  427. */
  428. public void setMaximumIntegerDigits(int newValue) {
  429. maximumIntegerDigits = Math.max(0,newValue);
  430. if (minimumIntegerDigits > maximumIntegerDigits)
  431. minimumIntegerDigits = maximumIntegerDigits;
  432. }
  433. /**
  434. * Returns the minimum number of digits allowed in the integer portion of a
  435. * number.
  436. * @see #setMinimumIntegerDigits
  437. */
  438. public int getMinimumIntegerDigits() {
  439. return minimumIntegerDigits;
  440. }
  441. /**
  442. * Sets the minimum number of digits allowed in the integer portion of a
  443. * number. minimumIntegerDigits must be <= maximumIntegerDigits. If the
  444. * new value for minimumIntegerDigits exceeds the current value
  445. * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
  446. * the new value
  447. * @param newValue the minimum number of integer digits to be shown; if
  448. * less than zero, then zero is used. The concrete subclass may enforce an
  449. * upper limit to this value appropriate to the numeric type being formatted.
  450. * @see #getMinimumIntegerDigits
  451. */
  452. public void setMinimumIntegerDigits(int newValue) {
  453. minimumIntegerDigits = Math.max(0,newValue);
  454. if (minimumIntegerDigits > maximumIntegerDigits)
  455. maximumIntegerDigits = minimumIntegerDigits;
  456. }
  457. /**
  458. * Returns the maximum number of digits allowed in the fraction portion of a
  459. * number.
  460. * @see #setMaximumFractionDigits
  461. */
  462. public int getMaximumFractionDigits() {
  463. return maximumFractionDigits;
  464. }
  465. /**
  466. * Sets the maximum number of digits allowed in the fraction portion of a
  467. * number. maximumFractionDigits must be >= minimumFractionDigits. If the
  468. * new value for maximumFractionDigits is less than the current value
  469. * of minimumFractionDigits, then minimumFractionDigits will also be set to
  470. * the new value.
  471. * @param newValue the maximum number of fraction digits to be shown; if
  472. * less than zero, then zero is used. The concrete subclass may enforce an
  473. * upper limit to this value appropriate to the numeric type being formatted.
  474. * @see #getMaximumFractionDigits
  475. */
  476. public void setMaximumFractionDigits(int newValue) {
  477. maximumFractionDigits = Math.max(0,newValue);
  478. if (maximumFractionDigits < minimumFractionDigits)
  479. minimumFractionDigits = maximumFractionDigits;
  480. }
  481. /**
  482. * Returns the minimum number of digits allowed in the fraction portion of a
  483. * number.
  484. * @see #setMinimumFractionDigits
  485. */
  486. public int getMinimumFractionDigits() {
  487. return minimumFractionDigits;
  488. }
  489. /**
  490. * Sets the minimum number of digits allowed in the fraction portion of a
  491. * number. minimumFractionDigits must be <= maximumFractionDigits. If the
  492. * new value for minimumFractionDigits exceeds the current value
  493. * of maximumFractionDigits, then maximumIntegerDigits will also be set to
  494. * the new value
  495. * @param newValue the minimum number of fraction digits to be shown; if
  496. * less than zero, then zero is used. The concrete subclass may enforce an
  497. * upper limit to this value appropriate to the numeric type being formatted.
  498. * @see #getMinimumFractionDigits
  499. */
  500. public void setMinimumFractionDigits(int newValue) {
  501. minimumFractionDigits = Math.max(0,newValue);
  502. if (maximumFractionDigits < minimumFractionDigits)
  503. maximumFractionDigits = minimumFractionDigits;
  504. }
  505. // =======================privates===============================
  506. private static NumberFormat getInstance(Locale desiredLocale,
  507. int choice)
  508. {
  509. /* try the cache first */
  510. String[] numberPatterns = (String[])cachedLocaleData.get(desiredLocale);
  511. if (numberPatterns == null) { /* cache miss */
  512. ResourceBundle resource = ResourceBundle.getBundle
  513. ("java.text.resources.LocaleElements", desiredLocale);
  514. numberPatterns = resource.getStringArray("NumberPatterns");
  515. /* update cache */
  516. cachedLocaleData.put(desiredLocale, numberPatterns);
  517. }
  518. return new DecimalFormat(numberPatterns[choice],
  519. new DecimalFormatSymbols(desiredLocale));
  520. }
  521. /**
  522. * First, read in the default serializable data.
  523. *
  524. * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
  525. * the stream was written by JDK 1.1,
  526. * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  527. * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
  528. * since the <code>int</code> fields were not present in JDK 1.1.
  529. * Finally, set serialVersionOnStream back to the maximum allowed value so that
  530. * default serialization will work properly if this object is streamed out again.
  531. *
  532. * @since JDK 1.2
  533. */
  534. private void readObject(ObjectInputStream stream)
  535. throws IOException, ClassNotFoundException
  536. {
  537. stream.defaultReadObject();
  538. if (serialVersionOnStream < 1) {
  539. // Didn't have additional int fields, reassign to use them.
  540. maximumIntegerDigits = maxIntegerDigits;
  541. minimumIntegerDigits = minIntegerDigits;
  542. maximumFractionDigits = maxFractionDigits;
  543. minimumFractionDigits = minFractionDigits;
  544. }
  545. serialVersionOnStream = currentSerialVersion;
  546. }
  547. /**
  548. * Write out the default serializable data, after first setting
  549. * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
  550. * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  551. * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
  552. * with the JDK 1.1 version of the stream format.
  553. *
  554. * @since JDK 1.2
  555. */
  556. private void writeObject(ObjectOutputStream stream)
  557. throws IOException
  558. {
  559. maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  560. (byte)maximumIntegerDigits;
  561. minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  562. (byte)minimumIntegerDigits;
  563. maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  564. (byte)maximumFractionDigits;
  565. minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
  566. (byte)minimumFractionDigits;
  567. stream.defaultWriteObject();
  568. }
  569. /**
  570. * Cache to hold the NumberPatterns of a Locale.
  571. */
  572. private static final Hashtable cachedLocaleData = new Hashtable(3);
  573. // Constants used by factory methods to specify a style of format.
  574. private static final int NUMBERSTYLE = 0;
  575. private static final int CURRENCYSTYLE = 1;
  576. private static final int PERCENTSTYLE = 2;
  577. private static final int SCIENTIFICSTYLE = 3;
  578. /**
  579. * True if the the grouping (i.e. thousands) separator is used when
  580. * formatting and parsing numbers.
  581. *
  582. * @serial
  583. * @see #isGroupingUsed
  584. */
  585. private boolean groupingUsed = true;
  586. /**
  587. * The maximum number of digits allowed in the integer portion of a
  588. * number. <code>maxIntegerDigits</code> must be greater than or equal to
  589. * <code>minIntegerDigits</code>.
  590. * <p>
  591. * <strong>Note:</strong> This field exists only for serialization
  592. * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
  593. * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
  594. * When writing to a stream, <code>maxIntegerDigits</code> is set to
  595. * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
  596. * whichever is smaller. When reading from a stream, this field is used
  597. * only if <code>serialVersionOnStream</code> is less than 1.
  598. *
  599. * @serial
  600. * @see #getMaximumIntegerDigits
  601. */
  602. private byte maxIntegerDigits = 40;
  603. /**
  604. * The minimum number of digits allowed in the integer portion of a
  605. * number. <code>minimumIntegerDigits</code> must be less than or equal to
  606. * <code>maximumIntegerDigits</code>.
  607. * <p>
  608. * <strong>Note:</strong> This field exists only for serialization
  609. * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
  610. * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
  611. * When writing to a stream, <code>minIntegerDigits</code> is set to
  612. * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
  613. * whichever is smaller. When reading from a stream, this field is used
  614. * only if <code>serialVersionOnStream</code> is less than 1.
  615. *
  616. * @serial
  617. * @see #getMinimumIntegerDigits
  618. */
  619. private byte minIntegerDigits = 1;
  620. /**
  621. * The maximum number of digits allowed in the fractional portion of a
  622. * number. <code>maximumFractionDigits</code> must be greater than or equal to
  623. * <code>minimumFractionDigits</code>.
  624. * <p>
  625. * <strong>Note:</strong> This field exists only for serialization
  626. * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
  627. * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
  628. * When writing to a stream, <code>maxFractionDigits</code> is set to
  629. * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
  630. * whichever is smaller. When reading from a stream, this field is used
  631. * only if <code>serialVersionOnStream</code> is less than 1.
  632. *
  633. * @serial
  634. * @see #getMaximumFractionDigits
  635. */
  636. private byte maxFractionDigits = 3; // invariant, >= minFractionDigits
  637. /**
  638. * The minimum number of digits allowed in the fractional portion of a
  639. * number. <code>minimumFractionDigits</code> must be less than or equal to
  640. * <code>maximumFractionDigits</code>.
  641. * <p>
  642. * <strong>Note:</strong> This field exists only for serialization
  643. * compatibility with JDK 1.1. In JDK 1.2 and higher, the new
  644. * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
  645. * When writing to a stream, <code>minFractionDigits</code> is set to
  646. * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
  647. * whichever is smaller. When reading from a stream, this field is used
  648. * only if <code>serialVersionOnStream</code> is less than 1.
  649. *
  650. * @serial
  651. * @see #getMinimumFractionDigits
  652. */
  653. private byte minFractionDigits = 0;
  654. /**
  655. * True if this format will parse numbers as integers only.
  656. *
  657. * @serial
  658. * @see #isParseIntegerOnly
  659. */
  660. private boolean parseIntegerOnly = false;
  661. // new fields for 1.2. byte is too small for integer digits.
  662. /**
  663. * The maximum number of digits allowed in the integer portion of a
  664. * number. <code>maximumIntegerDigits</code> must be greater than or equal to
  665. * <code>minimumIntegerDigits</code>.
  666. *
  667. * @serial
  668. * @since JDK 1.2
  669. * @see #getMaximumIntegerDigits
  670. */
  671. private int maximumIntegerDigits = 40;
  672. /**
  673. * The minimum number of digits allowed in the integer portion of a
  674. * number. <code>minimumIntegerDigits</code> must be less than or equal to
  675. * <code>maximumIntegerDigits</code>.
  676. *
  677. * @serial
  678. * @since JDK 1.2
  679. * @see #getMinimumIntegerDigits
  680. */
  681. private int minimumIntegerDigits = 1;
  682. /**
  683. * The maximum number of digits allowed in the fractional portion of a
  684. * number. <code>maximumFractionDigits</code> must be greater than or equal to
  685. * <code>minimumFractionDigits</code>.
  686. *
  687. * @serial
  688. * @since JDK 1.2
  689. * @see #getMaximumFractionDigits
  690. */
  691. private int maximumFractionDigits = 3; // invariant, >= minFractionDigits
  692. /**
  693. * The minimum number of digits allowed in the fractional portion of a
  694. * number. <code>minimumFractionDigits</code> must be less than or equal to
  695. * <code>maximumFractionDigits</code>.
  696. *
  697. * @serial
  698. * @since JDK 1.2
  699. * @see #getMinimumFractionDigits
  700. */
  701. private int minimumFractionDigits = 0;
  702. static final int currentSerialVersion = 1;
  703. /**
  704. * Describes the version of <code>NumberFormat</code> present on the stream.
  705. * Possible values are:
  706. * <ul>
  707. * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
  708. * In this version, the <code>int</code> fields such as
  709. * <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
  710. * fields such as <code>maxIntegerDigits</code> are used instead.
  711. *
  712. * <li><b>1</b>: the JDK 1.2 version of the stream format. The values of the
  713. * <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
  714. * and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
  715. * are used instead.
  716. * </ul>
  717. * When streaming out a <code>NumberFormat</code>, the most recent format
  718. * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
  719. * is always written.
  720. *
  721. * @serial
  722. * @since JDK 1.2
  723. */
  724. private int serialVersionOnStream = currentSerialVersion;
  725. // Removed "implements Cloneable" clause. Needs to update serialization
  726. // ID for backward compatibility.
  727. static final long serialVersionUID = -2308460125733713944L;
  728. }