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

Align the specification of java.util.Formatter float conversions to the implementation

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 21
    • core-libs
    • None
    • behavioral
    • low
    • Document existing variation from the spec and, in some rare circumstances, the outcomes of `e`, `f`, and `g` conversions may slightly differ from the ones in earlier releases.
    • Java API
    • SE

      Summary

      There's a long standing mismatch between the java.util.Formatter specification for the e, f, and g conversions on float values, and the implementation.

      Problem

      The java.util.Formatter specification for the e, f, and g conversions on a float value refers to the outcome of Float.toString(float). However, the implementation first converts a float value to a double value (without loss of precision), and then follows the specification for the corresponding e, f, and g conversions on that double value.

      Another, minor issue is that this CSR is also related to an implementation change, whereas in some rare circumstances, the outcomes of e, f, and g conversions may slightly differ from the ones in earlier releases.

      Solution

      Since the current behavior is long standing, the solution for the main change is to adapt the specification to match the implementation.

      The minor change related to slight differences in the outcomes is covered by the Release Note JDK-8301383

      Specification

      --- a/src/java.base/share/classes/java/util/Formatter.java
      +++ b/src/java.base/share/classes/java/util/Formatter.java
      @@ -1260,6 +1260,9 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
        *     id="scientific">computerized scientific notation</a>.  The <a
        *     href="#L10nAlgorithm">localization algorithm</a> is applied.
        *
      + *     <p> A {@code float} or {@link Float} argument is first converted to
      + *     {@code double} or {@link Double}, without loss of precision.
      + *
        *     <p> The formatting of the magnitude <i>m</i> depends upon its value.
        *
        *     <p> If <i>m</i> is NaN or infinite, the literal strings "NaN" or
      @@ -1291,8 +1294,8 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
        *     <i>m</i> or <i>a</i> is equal to the precision.  If the precision is not
        *     specified then the default value is {@code 6}. If the precision is less
        *     than the number of digits which would appear after the decimal point in
      - *     the string returned by {@link Float#toString(float)} or {@link
      - *     Double#toString(double)} respectively, then the value will be rounded
      + *     the string returned by {@link
      + *     Double#toString(double)}, 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.
        *     For a canonical representation of the value, use {@link
      @@ -1342,6 +1345,9 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
        *     format</a>.  The <a href="#L10nAlgorithm">localization algorithm</a> is
        *     applied.
        *
      + *     <p> A {@code float} or {@link Float} argument is first converted to
      + *     {@code double} or {@link Double}, without loss of precision.
      + *
        *     <p> The result is a string that represents the sign and magnitude
        *     (absolute value) of the argument.  The formatting of the sign is
        *     described in the <a href="#L10nAlgorithm">localization
      @@ -1360,8 +1366,8 @@ import sun.util.locale.provider.ResourceBundleBasedAdapter;
        *     <i>m</i> or <i>a</i> is equal to the precision.  If the precision is not
        *     specified then the default value is {@code 6}. If the precision is less
        *     than the number of digits which would appear after the decimal point in
      - *     the string returned by {@link Float#toString(float)} or {@link
      - *     Double#toString(double)} respectively, then the value will be rounded
      + *     the string returned by {@link
      + *     Double#toString(double)}, 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.
        *     For a canonical representation of the value, use {@link

            rgiulietti Raffaello Giulietti
            rgiulietti Raffaello Giulietti
            Joe Darcy
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: