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
- csr of
-
JDK-8300869 Make use of the Double.toString(double) algorithm in java.util.Formatter
- Closed
- relates to
-
JDK-8301383 Release Note: `java.util.Formatter` May Return Slightly Different Results on `double` and `float`
- Resolved