JDK-8291240 : JDK 19 and 20 slightly change double precision
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 19,20
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: linux_ubuntu
  • CPU: x86_64
  • Submitted: 2022-07-27
  • Updated: 2022-07-29
Related Reports
Relates :  
Relates :  
Relates :  
Description
While trying to run unit tests of Apache POI with JDK 19 and 20 eary access builds, we found a small difference in handling of very small "double" numbers.

This may be intentional, but I could not find any mentioning in the release notes of changes in this area.

How to reproduce: 

The following unit-test works in JDKs up to 18, but fails in latest JDK 19 and JDK 20 early access builds.

Reproducing code-snippet:

        assertEquals("1.0E-323",
                Double.toString(0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d));

Failure:


org.opentest4j.AssertionFailedError: 
Expected :1.0E-323
Actual   :9.9E-324

Comments
In retrospect, I agree [~dholmes]'s suggestion for a release note for double string output is a good one; it would provide documentation for conscientious testers to know any observed change using JDK 19 has an explanation.
28-07-2022

That would suffice when someone does spot a difference (as in this case) and needs to know whether the difference might be a bug. The RN could also give an example, such as the one is this issue.
28-07-2022

The change affects a vanishing minority of the cases. It's hard to tell how many, though. A release note would necessarily be quite vague, because describing _which_ of this tiny minority of cases is affected is not possible. Thus, the only value of a release note is reduced to a mere warning that the spec has changed and that some values will be converted to shorter strings and some (in the subnormal range, like the one reported) to a different, never longer string representing a better decimal.
27-07-2022

I am surprised the CSR for JDK-4511638 did not recommend a Release Note for this change. I would recommend one now for JDK 19.
27-07-2022

JDK-8202555, the CSR of JDK-4511638, specifies the details of the conversion. Let x be the double closest to 1e-323 (the long literal in the code snippet above). The full decimal expansion of x begins with 9.88131... 10^(-324). All decimals with a 1 or 2 digits significand that round to x are: 7.5e-324, ..., 9.8e-324, 9.9e-324, 1e-323, 1.1e-323, 1.2e-323 among these, the spec mandates determining the one closest to x, so the method correctly chooses 9.9e-324.
27-07-2022

Floating-point behaviour is not handled by the VM. Moving to core-libs. I would have to assume this is JDK-4511638 as the problem seems to match the description there.
27-07-2022

Related changes in JDK 19: * JDK-4511638 - https://github.com/openjdk/jdk/commit/72bcf2aa03d53b0f68eb07a902575b4e8628d859 * JDK-8285477 - https://github.com/openjdk/jdk/commit/fb605944b5b734c8b47a9122e7ab3d3dcf55f71e
27-07-2022