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

Formatter '%g' conversion uses wrong format for BigDecimal rounding up to limits

    XMLWordPrintable

Details

    • b19
    • Verified

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10, although the OS is probably irrelevant.

      Reproduced both with Java 8 and 17ea:

      openjdk version "1.8.0_222"
      OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_222-b10)
      OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.222-b10, mixed mode)

      openjdk version "17-ea" 2021-09-14
      OpenJDK Runtime Environment (build 17-ea+5-266)
      OpenJDK 64-Bit Server VM (build 17-ea+5-266, mixed mode, sharing)

      A DESCRIPTION OF THE PROBLEM :
      When all the following apply:

      * using the '%g' conversion with a BigDecimal,
      * the value of the BigDecimal is < 10^-4 (resp. 10^precision)
      * the *rounded* value to the specified precision = 10^-4 (resp. 10^precision)

      Then, Formatter will format the value with scientific notation instead of fixed notation (resp. fixed instead of scientific).

      Note that the JavaDoc clearly specifies that:

      > After rounding for the precision, the formatting of the resulting magnitude m depends on its value.

      Since the value is rounded up to 10^4 (resp. 10^precision), it should be displayed with fixed (resp. scientific) precision.

      Floats and Doubles are correctly displayed depending on their value after rounding.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Using the test file test/Test.java provided below:

      $ javac -d bin test/Test.java
      $ java -cp bin test.Test

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      0.000100000
      0.000100000
      0.000100000

      1.00000000e+14
      1.000e+04
      1.00000000e+14
      ACTUAL -
      0.000100000
      0.000100000
      1.00000e-04

      1.00000000e+14
      1.000e+04
      1000000000

      ---------- BEGIN SOURCE ----------
      package test;

      import java.math.BigDecimal;

      public class Test {
        public static void main(String[] args) {
          // Rounding to 10^-4
          System.out.println(String.format("%g", 0.00009999999999999995));
          System.out.println(String.format("%g", 0.00009999999f));
          System.out.println(String.format("%g", new BigDecimal("0.00009999999999999999995"))); // !!
          
          System.out.println("");

          // Rounding to 10^precision
          System.out.println(String.format("%.9g", 999999.9999994322e+8));
          System.out.println(String.format("%.4g", 999.961e1f));
          System.out.println(String.format("%.9g", new BigDecimal("999999.999999432168754e+3"))); // !!
        }
      }

      ---------- END SOURCE ----------

      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              igraves Ian Graves
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: