-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Java: in correct rounding to two digits #83
Comments
I just tried to replicate this issue as part of my efforts to port RYU to Scala Native. Please pardon
I get the same output 1.0E-323 for both 1.0E-323 and 9.9E-324. Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
1.0E-323
1.0E-323 Using the web site avoids an peculiarities on my local machine but uses I get the same results when I run the same code on my local 64 bit machine running Does RYU truely have a bug here or am I not seeing something, either subtle or obvious? Thank you, Lee PS: The rest of the RYU port to Scala Native seems to be running just fine. Thank you for RYU. |
Well, whether the current output is correct or not depends on what exactly the specification for Double.toString says. Unfortunately, it's not very precise in a mathematical sense, and this is a rather esoteric corner case. The spec basically says that we should print (a) the shortest number, with (b) at least two digits, that (c) parses back to the original number and (d) is closest to the exact value. Ignoring (b), the shortest number would clearly be 1e-323. The crux of the matter is the requirement (b). Should we compute the shortest number, and then print two digits? Then it should be 1.0e-323. Should we compute the two-digit number that is closest to the original input? Then it should be 9.9e-324. Clearly, we have to pick one of these interpretations. In my opinion, the second interpretation is slightly preferable, that is, I prefer the printed number to be slightly closer to the exact value. We have two digits, so why not use them? There was a brief discussion of this on one of the OpenJDK mailing lists, and there was no strong argument against this interpretation. And yes, that implies that the current OpenJDK implementation of Double.toString is incorrect. There are actually more cases where it is incorrect, and more clearly so - there are some cases where it prints too many digits (which is certainly better than too few!). |
@ulfjack Thank you for the additional description. Java does not have as long a history as C but it still has 25 or so years I suspect that I an not the only developer who would evaluate Ryu I would have to implement a workaround to avoid spending the With full support for your efforts, I say "Your field, your rules" but |
Some say that Java is defined by its abundant implementation "quirks". If the goal is to have Ryu follow a spec more closely (a laudable goal), I am probably going to have to take the "Java-like, not one-to-one Java" approach |
The discussion thread in upstream is about merging a new implementation that returns 9.9E-324 in this case, as well as a more mathematically precise specification. I tested Ryu against the new implementation and discovered that Ryu returns 1.0E-323 in this case (but otherwise found no differences in output). I don't know if or when upstream will merge a new implementation and whether it will be the one that was discussed. In any case, I can clarify in the README that the current behavior differs from Double.toString in some cases. |
There aren't a lot of one-digit and two-digit numbers across all possible double values, so I could check all of them against OpenJDK. |
The Java implementation sometimes doesn't output the closest two-digit representation of a number, but instead rounds to one digit (correctly), and then appends a '0'.
Known examples:
1.0E-323
should be9.9E-324
1.0E-322
should be9.9E-323
The text was updated successfully, but these errors were encountered: