Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8185777

Document default rounding mode in NumberFormat

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 10
    • core-libs
    • None
    • behavioral
    • minimal
    • Documenting existing behavior.
    • Java API
    • SE

      Summary

      Specifications for NumberFormat and String.format APIs do not specify the default RoundingMode used for formatting the numbers. The default rounding mode used by NumberFormat (HALF_EVEN) may be inconsistent with default rounding modes used by other core jdk classes, such as java.util.Formatter (HALF_UP). This concern was raised in JDK-6979872, but can not be changed to maintain backward compatibility.

      Problem

      • NumberFormat uses HALF_EVEN as its default RoundingMode for formatting the floating point numbers, which is not documented in API specification.
      • String.format methods uses HALF_UP as its RoundingMode for rounding the numbers, which is not documented in the API specification.

      Solution

      • Document the default rounding mode used by NumberFormat for rounding floating point numbers. To maintain behavioural compatibility with the existing implementations, add the behaviour requirement in the @implSpec tag

      • It may be bit odd adding only the rounding behavior in String.format() method and not mentioning other java.util.Formatter formatting behavior. Since those String.format() methods have "@see java.util.Formatter" clauses, it can be expected from readers of String.format to refer to java.util.Formatter, hence no change is required for String.format() specifications. However, it is observed that the javadoc of java.util.Formatter is still referring to deprecated java.math.BigDecimal.ROUND_HALF_UP, hence the specification of java.util.Formatter should be changed to refer to java.math.RoundingMode.HALF_UP

      Specification

      1) Changing the specification of NumberFormat at class level including the details about its static factory methods

      from:

       * @implSpec The {@link #format(double, StringBuffer, FieldPosition)},
       * {@link #format(long, StringBuffer, FieldPosition)} and
       * {@link #parse(String, ParsePosition)} methods may throw
       * {@code NullPointerException}, if any of their parameter is {@code null}.
       * The subclass may provide its own implementation and specification about
       * {@code NullPointerException}.

      to:

       * @implSpec
       * <ul><li>
       * The {@link #format(double, StringBuffer, FieldPosition)},
       * {@link #format(long, StringBuffer, FieldPosition)} and
       * {@link #parse(String, ParsePosition)} methods may throw
       * {@code NullPointerException}, if any of their parameter is {@code null}.
       * The subclass may provide its own implementation and specification about
       * {@code NullPointerException}.</li>
       * 
       * <li><b>Rounding</b>: {@code NumberFormat} provides rounding modes defined
       * in {@link java.math.RoundingMode} for formatting the numbers. By default,
       * it uses {@linkplain java.math.RoundingMode#HALF_EVEN
       * round half-even algorithm}. To change the rounding mode use
       * {@link #setRoundingMode(java.math.RoundingMode) setRoundingMode}.
       * The {@code NumberFormat} returned by its static factory methods is
       * configured to round floating point numbers using half-even
       * rounding (see {@link java.math.RoundingMode#HALF_EVEN
       * RoundingMode.HALF_EVEN}) for formatting.
       * </li></ul>

      2) Changing the specification of java.util.Formatter on

      a) line 1231-1233

      from :

       *     Double#toString(double)} respectively, then the value will be rounded
       *     using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
       *     algorithm}.  Otherwise, zeros may be appended to reach the precision.

      to:

       *     Double#toString(double)} respectively, then the value will be rounded
       *     using the {@linkplain java.math.RoundingMode#HALF_UP round half up
       *     algorithm}.  Otherwise, zeros may be appended to reach the precision.

      b) line 1300-1302

      from:

       *     Double#toString(double)} respectively, then the value will be rounded
       *     using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
       *     algorithm}.  Otherwise, zeros may be appended to reach the precision.

      to:

       *     Double#toString(double)} respectively, then the value will be rounded
       *     using the {@linkplain java.math.RoundingMode#HALF_UP round half up
       *     algorithm}.  Otherwise, zeros may be appended to reach the precision.

      c) line 1463-1465

      from:

       *     the value will be rounded using the
       *     {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
       *     algorithm}.  Otherwise, zeros may be appended to reach the precision.

      to:

       *     the value will be rounded using the
       *     {@linkplain java.math.RoundingMode#HALF_UP round half up
       *     algorithm}.  Otherwise, zeros may be appended to reach the precision.

      d) line 1526-1528

      from:

       *     then the value will be rounded using the
       *     {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
       *     algorithm}.  Otherwise, zeros may be appended to reach the precision.

      to:

       *     then the value will be rounded using the
       *     {@linkplain java.math.RoundingMode#HALF_UP round half up
       *     algorithm}.  Otherwise, zeros may be appended to reach the precision

      .

            nishjain Nishit Jain
            asaha Abhijit Saha
            Naoto Sato
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: