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

Extra '0' in java.util.Formatter for '%012a' conversion with a sign character

XMLWordPrintable

    • b14
    • Verified

      ADDITIONAL SYSTEM INFORMATION :
      Reproduced on Windows 10, but I do not expect the OS to be relevant.

      Reproduced with Java 1.8.0_222 and "17-ea" 2021-09-14:

      >java -version
      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)

      >java -version
      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 the following conditions meet:

      * Use a `%a` conversion with the `0` flag and a width (e.g., `"%012a"`)
      * When the result has a sign character (`-`, or `+` or ` ` (space) with the respective flags)

      then 1 too many padding '0's is inserted, resulting in a formatted string 1 char longer than the specified width.

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

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

      Observe that the right-most `|` do not all align, even though they should (in each block). Every line marked with a `// !!` comment in the source code emits one character '0' too many in the padding.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      |0x000000000000000000000000.0p0|
      | 0x00000000000000000000000.0p0|
      |+0x00000000000000000000000.0p0|
      |-0x00000000000000000000000.0p0|
      |-0x00000000000000000000000.0p0|
      |-0x00000000000000000000000.0p0|
      |-0x1.0p1 |
      | 0x1.0p1 |
      |0x000000000000000000000001.0p1|
      |-0x00000000000000000000001.0p1|
      | 0x00000000000000000000001.0p1|
      |+0x00000000000000000000001.0p1|
      |-0x1.26580b480ca46p30 |
      | 0x1.26580b480ca46p30 |
      |0x00000000001.26580b480ca46p30|
      |-0x0000000001.26580b480ca46p30|
      | 0x0000000001.26580b480ca46p30|
      |+0x0000000001.26580b480ca46p30|

      |0x000000.0p0|
      | 0x00000.0p0|
      |+0x00000.0p0|
      |-0x00000.0p0|
      |-0x00000.0p0|
      |-0x00000.0p0|
      |-0x1.0p1 |
      | 0x1.0p1 |
      |0x000001.0p1|
      |-0x00001.0p1|
      | 0x00001.0p1|
      |+0x00001.0p1|
      |-0x1.2p30 |
      | 0x1.2p30 |
      |0x00001.2p30|
      |-0x0001.2p30|
      | 0x0001.2p30|
      |+0x0001.2p30|

      ACTUAL -
      |0x000000000000000000000000.0p0|
      | 0x000000000000000000000000.0p0|
      |+0x000000000000000000000000.0p0|
      |-0x000000000000000000000000.0p0|
      |-0x000000000000000000000000.0p0|
      |-0x000000000000000000000000.0p0|
      |-0x1.0p1 |
      | 0x1.0p1 |
      |0x000000000000000000000001.0p1|
      |-0x000000000000000000000001.0p1|
      | 0x000000000000000000000001.0p1|
      |+0x000000000000000000000001.0p1|
      |-0x1.26580b480ca46p30 |
      | 0x1.26580b480ca46p30 |
      |0x00000000001.26580b480ca46p30|
      |-0x00000000001.26580b480ca46p30|
      | 0x00000000001.26580b480ca46p30|
      |+0x00000000001.26580b480ca46p30|

      |0x000000.0p0|
      | 0x000000.0p0|
      |+0x000000.0p0|
      |-0x000000.0p0|
      |-0x000000.0p0|
      |-0x000000.0p0|
      |-0x1.0p1 |
      | 0x1.0p1 |
      |0x000001.0p1|
      |-0x000001.0p1|
      | 0x000001.0p1|
      |+0x000001.0p1|
      |-0x1.2p30 |
      | 0x1.2p30 |
      |0x00001.2p30|
      |-0x00001.2p30|
      | 0x00001.2p30|
      |+0x00001.2p30|


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

      public class Test {
        public static void main(String[] args) {
          System.out.println(String.format("|%030a|", 0.0));
          System.out.println(String.format("|% 030a|", 0.0)); // !!
          System.out.println(String.format("|%+030a|", 0.0)); // !!
          System.out.println(String.format("|%030a|", -0.0)); // !!
          System.out.println(String.format("|% 030a|", -0.0)); // !!
          System.out.println(String.format("|%+030a|", -0.0)); // !!

          System.out.println(String.format("|%- 30a|", -2.0));
          System.out.println(String.format("|%- 30a|", 2.0));
          System.out.println(String.format("|%030a|", 2.0));
          System.out.println(String.format("|%030a|", -2.0)); // !!
          System.out.println(String.format("|% 030a|", 2.0)); // !!
          System.out.println(String.format("|%+030a|", 2.0)); // !!

          System.out.println(String.format("|%- 30a|", -1234567890.012345678));
          System.out.println(String.format("|%- 30a|", 1234567890.012345678));
          System.out.println(String.format("|%030a|", 1234567890.012345678));
          System.out.println(String.format("|%030a|", -1234567890.012345678)); // !!
          System.out.println(String.format("|% 030a|", 1234567890.012345678)); // !!
          System.out.println(String.format("|%+030a|", 1234567890.012345678)); // !!
          
          System.out.println("");

          System.out.println(String.format("|%012.0a|", 0.0));
          System.out.println(String.format("|% 012.0a|", 0.0)); // !!
          System.out.println(String.format("|%+012.0a|", 0.0)); // !!
          System.out.println(String.format("|%012.0a|", -0.0)); // !!
          System.out.println(String.format("|% 012.0a|", -0.0)); // !!
          System.out.println(String.format("|%+012.0a|", -0.0)); // !!

          System.out.println(String.format("|%- 12.0a|", -2.0));
          System.out.println(String.format("|%- 12.0a|", 2.0));
          System.out.println(String.format("|%012.0a|", 2.0));
          System.out.println(String.format("|%012.0a|", -2.0)); // !!
          System.out.println(String.format("|% 012.0a|", 2.0)); // !!
          System.out.println(String.format("|%+012.0a|", 2.0)); // !!

          System.out.println(String.format("|%- 12.0a|", -1234567890.012345678));
          System.out.println(String.format("|%- 12.0a|", 1234567890.012345678));
          System.out.println(String.format("|%012.0a|", 1234567890.012345678));
          System.out.println(String.format("|%012.0a|", -1234567890.012345678)); // !!
          System.out.println(String.format("|% 012.0a|", 1234567890.012345678)); // !!
          System.out.println(String.format("|%+012.0a|", 1234567890.012345678)); // !!
        }
      }


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

      FREQUENCY : always


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

              Created:
              Updated:
              Resolved: