[PATCH] 4511638: Double.toString(double) sometimes produces incorrect results

Raffaello Giulietti raffaello.giulietti at gmail.com
Thu Sep 27 15:37:13 UTC 2018


Hi Ulf,


On 2018-09-27 16:40, Ulf Adams wrote:
> Hi Raffaello,
> 
> I am the author of a recent publication on double to string conversion 
> [1] - the Ryu algorithm. I've been aware of the problems with the Jdk 
> for several years, and am very much looking forward to improvements in 
> correctness and performance in this area.
> 

What a coincidence! I'm happy to hear that the quest for better 
floating->string conversions has not stopped. Tomorrow I'll download 
your paper and have a look at it during the weekend.



> I have done some testing against my Java implementation of the Ryu 
> algorithm described in the linked paper. Interestingly, I've found a few 
> cases where they output different results. In particular:
> 1.0E-323 is printed as 9.9E-324
> 1.0E-322 is printed as 9.9E-323

If Ryu also produces 1 digit long outputs, then your results above are 
correct. But then Ryu should also output 5.0E-324 rather than 4.9E-324, 
for example.
Even better, it should output 5E-324, 1E-323 and 1E-322 because adding 
the .0 part might confuse a human reader to believe that 2 digits are 
really needed. But then 4.9E-324, 9.9E-324 and 9.9E-323 are closer to 
the double.

2 digits are for backward compatibility with the existing spec which 
requires at least one digit to the right of the decimal point.


> 
> It's likely that there are more such cases - I only ran a sample of 
> double-precision numbers. Arguably, 9.9 is the correctly rounded 2-digit 
> output and Ryu is incorrect here. That's what you get when you have a 
> special case for Java without a correctness proof. :-(
> 
> In terms of performance, this algorithm performs almost exactly the same 
> as my Java implementation of Ryu, although I'd like to point out that my 
> C implementation of Ryu is quite a bit faster (though note that it 
> generates different output, in particular, it only outputs a single 
> digit of precision in the above cases, rather than two), and I didn't 
> backport all the performance improvements from the Java version, yet. It 
> looks like this is not coincidence - as far as I can see so far, it's 
> algorithmically very similar, although it manages to avoid the loop I'm 
> using in Ryu to find the shortest representation.
> 
> I have a few comments:
> 
>       *     <li> It rounds to {@code v} according to the usual 
> round-to-closest
>       *     rule of IEEE 754 floating-point arithmetic.
> - Since you're spelling out the rounding rules just below, this is 
> duplicated, and by itself, it's unclear since it doesn't specify the 
> specific sub-type (round half even).
> 

I tried to save as much of the original spec wording as possible. 
Perhaps it isn't worthwhile.



> - Naming: I'd strongly suggest to use variable names that relate to 
> what's stored, e.g., m for mantissa, e for exponent, etc.
> 

I currently prefer to be consistent with a forthcoming paper of mine on 
the subject. But thanks for the suggestion.



> - What's not clear to me is how the algorithm determines how many digits 
> to print.
> 

You'll have to wait for the paper.


> - Also, it might be nicer to move the long multiplications to a helper 
> method - at least from a short look, it looks like the computations of 
> vn, vnl, and vnr are identical.
> 

I tried several variants: the current one seems to be the faster with 
the current optimizations of C2. Some day I'll also try with Graal.



> - I looked through the spec, and it looks like all cases are 
> well-defined. Yay!
> 
> I will need some more time to do a more thorough review of the code and 
> more testing for differences. Unfortunately, I'm also traveling the next 
> two weeks, so this might take a bit of time.
> 

I thank you in advance for your willingness to review the code but my 
understanding is that only the officially appointed reviewers can 
approve OpenJDK contributions, which is of course a good policy. 
Besides, as two Andrews engineers from RedHat correctly observe, 
understanding the rationale of the code without the planned accompanying 
paper is hard.



> I'm not a contributor to the Jdk, and this isn't my full-time job. I was 
> lurking here because I was going to send a patch for the double to 
> string conversion code myself (based on Ryu).
> 

All my efforts on this projects are done in my unpaid spare time, too.


> Thanks,
> 
> -- Ulf
> 
 > [1] https://dl.acm.org/citation.cfm?id=3192369
 > [2] https://github.com/google/double-conversion
 > [3] https://en.wikipedia.org/wiki/Rounding
 >


Thank you
Raffaello








More information about the core-libs-dev mailing list