RFR: 4511638: Double.toString(double) sometimes produces incorrect results

Joe Darcy joe.darcy at oracle.com
Thu Apr 15 19:13:32 UTC 2021


Hi Jan,

I recommend using {Double, Float}.toHexString to get a straightforward 
textual form of the floating-point values. The hex string is isomorphic 
to the big-level value, but is (more) human readable as a numerical 
quantity.

-Joe

On 4/15/2021 10:26 AM, Jan Lahoda wrote:
> On Thu, 8 Apr 2021 21:12:21 GMT, Raffaello Giulietti <github.com+70726043+rgiulietti at openjdk.org> wrote:
>
>> Hello,
>>
>> here's a PR for a patch submitted on March 2020 [1](https://cr.openjdk.java.net/~bpb/4511638/webrev.04/) when Mercurial was a thing.
>>
>> The patch has been edited to adhere to OpenJDK code conventions about multi-line (block) comments. Nothing in the code proper has changed, except for the addition of redundant but clarifying parentheses in some expressions.
>>
>>
>> Greetings
>> Raffaello
> Regarding the `ElementStructureTest`, it prints the API elements (including compile-time constants) computes hash for the printed API and compares it with an expected hash. doubles and floats are printed using String.valueOf, and it apparently changed for `Float.MIN_NORMAL` from `1.17549435E-38` to `1.1754944E-38` (I assume that is intentional). So regarding `ElementStructureTest.java` we can just update it. How about this?
>
>
> diff --git a/test/langtools/tools/javac/sym/ElementStructureTest.java b/test/langtools/tools/javac/sym/ElementStructureTest.java
> index 29776ce28c2..d15f2447749 100644
> --- a/test/langtools/tools/javac/sym/ElementStructureTest.java
> +++ b/test/langtools/tools/javac/sym/ElementStructureTest.java
> @@ -121,29 +121,22 @@ import toolbox.ToolBox;
>    */
>   public class ElementStructureTest {
>   
> -    static final byte[] hash6 = new byte[] {
> -        (byte) 0x99, (byte) 0x34, (byte) 0x82, (byte) 0xCF,
> -        (byte) 0xE0, (byte) 0x53, (byte) 0xF3, (byte) 0x13,
> -        (byte) 0x4E, (byte) 0xCF, (byte) 0x49, (byte) 0x32,
> -        (byte) 0xB7, (byte) 0x52, (byte) 0x0F, (byte) 0x68
> -    };
>       static final byte[] hash7 = new byte[] {
> -        (byte) 0x3C, (byte) 0x03, (byte) 0xEA, (byte) 0x4A,
> -        (byte) 0x62, (byte) 0xD2, (byte) 0x18, (byte) 0xE5,
> -        (byte) 0xA5, (byte) 0xC2, (byte) 0xB7, (byte) 0x85,
> -        (byte) 0x90, (byte) 0xFA, (byte) 0x98, (byte) 0xCD
> +        (byte) 0xA7, (byte) 0x3B, (byte) 0x91, (byte) 0xF6,
> +        (byte) 0xEF, (byte) 0x99, (byte) 0x07, (byte) 0xF2,
> +        (byte) 0x79, (byte) 0xAB, (byte) 0x19, (byte) 0xF4,
> +        (byte) 0x59, (byte) 0x44, (byte) 0xF7, (byte) 0x65
>       };
>       static final byte[] hash8 = new byte[] {
> -        (byte) 0x24, (byte) 0x38, (byte) 0x52, (byte) 0x1C,
> -        (byte) 0x5E, (byte) 0x83, (byte) 0x82, (byte) 0xE6,
> -        (byte) 0x41, (byte) 0xC2, (byte) 0xDD, (byte) 0x2A,
> -        (byte) 0xFD, (byte) 0xFF, (byte) 0x5E, (byte) 0x2F
> +        (byte) 0xF3, (byte) 0x93, (byte) 0xCA, (byte) 0x53,
> +        (byte) 0xFD, (byte) 0xA3, (byte) 0x5D, (byte) 0x57,
> +        (byte) 0xD2, (byte) 0xED, (byte) 0x39, (byte) 0xC5,
> +        (byte) 0x56, (byte) 0x62, (byte) 0xE0, (byte) 0x1F
>       };
>   
>       final static Map<String, byte[]> version2Hash = new HashMap<>();
>   
>       static {
> -        version2Hash.put("6", hash6);
>           version2Hash.put("7", hash7);
>           version2Hash.put("8", hash8);
>       }
> @@ -484,7 +477,7 @@ public class ElementStructureTest {
>                   return null;
>               try {
>                   analyzeElement(e);
> -                out.write(String.valueOf(e.getConstantValue()));
> +                writeConstant(e.getConstantValue());
>                   out.write("\n");
>               } catch (IOException ex) {
>                   ex.printStackTrace();
> @@ -514,6 +507,16 @@ public class ElementStructureTest {
>               throw new IllegalStateException("Should not get here.");
>           }
>   
> +        private void writeConstant(Object value) throws IOException {
> +            if (value instanceof Double) {
> +                out.write(Long.toString(Double.doubleToRawLongBits((Double) value)));
> +            } else if (value instanceof Float) {
> +                out.write(Integer.toString(Float.floatToRawIntBits((Float) value)));
> +            } else {
> +                out.write(String.valueOf(value));
> +            }
> +        }
> +
>       }
>   
>       final class TestFileManager implements JavaFileManager {
>
> -------------
>
> PR: https://git.openjdk.java.net/jdk/pull/3402


More information about the core-libs-dev mailing list