ADDITIONAL SYSTEM INFORMATION : Windows 11, Java 21.0.3-9 A DESCRIPTION OF THE PROBLEM : Problem simulated in simple jUnit test - in which it is displayed that with the usage of "BigDecimal.valueOf(double)" incorrect object is created (most likely due to the new way of 'toString' method in Double class) @Test void testDoubleConversion() { final String stringRepresentation = "0212467111917324511"; // after the conversion to double value is 2.12467111917324512E17 (this is OK) final double parsedDouble = Double.parseDouble(stringRepresentation); // after conversion to string - value is: 2.124671119173245E17 (last two digits are lost due to the new way of toString method in the Double class) final String backFromDouble = Double.toString(parsedDouble); // conversion back to double brings again the original value: 2.12467111917324512E17 final double parsedFromBackFromDouble = Double.parseDouble(backFromDouble); assertEquals(parsedDouble, parsedFromBackFromDouble); // with the usage of constructor BigDecimal holds the same value as parsedDouble: 212467111917324512 final BigDecimal bigDecimalFromDouble = new BigDecimal(parsedDouble); System.out.println(bigDecimalFromDouble); // with the usage of valueOf(double) precession is lost due to the new 'toString' method in the Double class: 2.12467111917324512E17 final BigDecimal bigDecimalFromValueOf = BigDecimal.valueOf(parsedDouble); System.out.println(bigDecimalFromValueOf); // compare fail due to the fact that 'bigDecimalFromDouble' is greater number (due to the lost of last 2 digits in 'valueOf' conversion) assertThat(bigDecimalFromDouble, Matchers.comparesEqualTo(bigDecimalFromValueOf)); } REGRESSION : Last worked in version 17.0.11 STEPS TO FOLLOW TO REPRODUCE THE PROBLEM : jUnit which simulates the issue is added in Description EXPECTED VERSUS ACTUAL BEHAVIOR : EXPECTED - Precession won't be lost during usage of "toString(double)" in BigDecimal class ACTUAL - Last two digits from the test are lost with the usage of toString(double) in BigDecimal class ---------- BEGIN SOURCE ---------- @Test void testDoubleConversion() { final String stringRepresentation = "0212467111917324511"; // after the conversion to double value is 2.12467111917324512E17 (this is OK) final double parsedDouble = Double.parseDouble(stringRepresentation); // after conversion to string - value is: 2.124671119173245E17 (last two digits are lost due to the new way of toString method in the Double class) final String backFromDouble = Double.toString(parsedDouble); // conversion back to double brings again the original value: 2.12467111917324512E17 final double parsedFromBackFromDouble = Double.parseDouble(backFromDouble); assertEquals(parsedDouble, parsedFromBackFromDouble); // with the usage of constructor BigDecimal holds the same value as parsedDouble: 212467111917324512 final BigDecimal bigDecimalFromDouble = new BigDecimal(parsedDouble); System.out.println(bigDecimalFromDouble); // with the usage of valueOf(double) precession is lost due to the new 'toString' method in the Double class: 2.12467111917324512E17 final BigDecimal bigDecimalFromValueOf = BigDecimal.valueOf(parsedDouble); System.out.println(bigDecimalFromValueOf); // compare fail due to the fact that 'bigDecimalFromDouble' is greater number (due to the lost of last 2 digits in 'valueOf' conversion) assertThat(bigDecimalFromDouble, Matchers.comparesEqualTo(bigDecimalFromValueOf)); } ---------- END SOURCE ---------- CUSTOMER SUBMITTED WORKAROUND : usage of "new BigDecimal(double)" instead of BigDecimal.valueOf(double) for Java 19 and above (most likely problem is caused by new implementation from https://bugs.openjdk.org/browse/JDK-4511638) FREQUENCY : always
|