-
Notifications
You must be signed in to change notification settings - Fork 6.2k
4511638: Double.toString(double) sometimes produces incorrect results #3402
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
Conversation
|
👋 Welcome back rgiulietti! A progress list of the required criteria for merging this PR into |
|
Forgot to add that other changes in the code are the use of switch expressions and the use of instanceof patterns. |
|
@rgiulietti The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
|
Hello, here's some background information for those that didn't follow the mailing list for the last couple of years. Some enjoyable properties of the novel algorithm:
See 3 for some (invented) Q&A. The last Q&A deals with your investment in time for an informed review. Greetings |
|
@rgiulietti Please issue the [1] https://wiki.openjdk.java.net/display/SKARA/Pull+Request+Commands#PullRequestCommands-/csr |
|
/csr needed |
|
@rgiulietti this pull request will not be integrated until the CSR request JDK-8202555 for issue JDK-4511638 has been approved. |
|
@bplb No, the CSR [1] (https://bugs.openjdk.java.net/browse/JDK-8202555) needs no updates. |
|
The langtools/tier1 test tools/javac/sym/ElementStructureTest.java fails on all 4 platforms supported by the automatic GH actions. Thanks |
OK, good. I wonder whether it should be moved back to |
|
Regarding the |
|
Mailing list message from Joe Darcy on core-libs-dev: Hi Jan, I recommend using {Double, Float}.toHexString to get a straightforward -Joe On 4/15/2021 10:26 AM, Jan Lahoda wrote: |
|
Hi Jan, I had to change a string in test However, I didn't change the definition of MIN_NORMAL in java.lang.Float because there it is already expressed in hex notation. As suggested before and by Joe, using the hex representation instead of the decimal would be more robust because the conversions from/to hex are almost trivial, hence much less subject to slight errors. So, rather than printing the raw bits as you suggest, you could use the hex string rendering instead. Thanks |
|
Sure, here you are: |
|
Fine, thanks! Will your change be integrated soon on master? (BTW, you could make use of instanceof pattern matching if you don't need backward compat ;-) ) |
|
@ rgiulietti, I thought you'd simply add the test change to your patch. But I can start a PR for it, if you prefer. |
|
@lahodaj Oh, my understanding was that yours is a permanent change worth of integrating anyway. But yes, I can add your change to my changeset. |
|
Modified |
| static final int Q_MAX = (1 << (W - 1)) - P; | ||
|
|
||
| /* 10^(E_MIN - 1) <= MIN_VALUE < 10^E_MIN */ | ||
| static final int E_MIN = -323; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that E_MIN/E_MAX/K_MIN/K_MAX are not used in production code.
I think it worth to move them to tests.
| * -d.ddddddddddddddddE-eee H + 7 characters | ||
| * where there are H digits d | ||
| */ | ||
| public final int MAX_CHARS = H + 7; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it be made static ?
|
Mailing list message from Raffaello Giulietti on core-libs-dev: Hi Andrey, thanks for your careful reading. I'll keep a note and collect yours with changes coming from other Greetings On 2021-04-18 23:19, Andrey Turbanov wrote: |
1 similar comment
|
Mailing list message from Raffaello Giulietti on core-libs-dev: Hi Andrey, thanks for your careful reading. I'll keep a note and collect yours with changes coming from other Greetings On 2021-04-18 23:19, Andrey Turbanov wrote: |
|
@rgiulietti This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
|
Hi, a reminder to keep PR [1] alive and to invite interested reviewers to The corresponding CSR is in [2] Greetings [1] #3402 |
| * The last entry must be for an exponent of K_MAX or more. | ||
| */ | ||
| private static final long[] g = { | ||
| /* -324 */ 0x4F0C_EDC9_5A71_8DD4L, 0x5B01_E8B0_9AA0_D1B5L, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not significant, but might this be clearer instead to comment the array elements on the right?
0x4F0C_EDC9_5A71_8DD4L, 0x5B01_E8B0_9AA0_D1B5L, // -324
| * | ||
| * [2] IEEE Computer Society, "IEEE Standard for Floating-Point Arithmetic" | ||
| * | ||
| * [3] Bouvier & Zimmermann, "Division-Free Binary-to-Decimal Conversion" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar comment concerning <cite/> tag as in MathUtils.
| /* Used for left-to-tight digit extraction */ | ||
| private static final int MASK_28 = (1 << 28) - 1; | ||
|
|
||
| private static final int NON_SPECIAL = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would these constants be better as an enum?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An enum would make much sense if it were used by other parts of the codebase, and then it would be moved to MathUtils.
This might well happen in the near future, when this code could be enhanced to be used in formatting conversions, like in "printf()" and friends.
| /* Index into bytes of rightmost valid character */ | ||
| private int index; | ||
|
|
||
| private DoubleToDecimal() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment like
/**
* Prevent instantiation.
*/
or
// Prevent instantiation of this class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The constructor is invoked, so the comment would be inappropriate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... but I added a throw in the constructor of MathUtils
| */ | ||
| final public class FloatToDecimal { | ||
| /* | ||
| * For full details about this code see the following references: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about <cite/>.
| /* Used for left-to-tight digit extraction */ | ||
| private static final int MASK_28 = (1 << 28) - 1; | ||
|
|
||
| private static final int NON_SPECIAL = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As these are shared with DoubleToDecimal would these constants be better moved to a common location, e.g., MathUtils whether converted to an enum or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as the values are constant ints, moving them to MathUtils is less robust. Changing any value would require remembering to recompile the "clients".
The move would make sense if these were an enum.
| /* Index into bytes of rightmost valid character */ | ||
| private int index; | ||
|
|
||
| private FloatToDecimal() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about preventing instantiation.
| /* 10^(E_MAX - 1) <= MAX_VALUE < 10^E_MAX */ | ||
| static final int E_MAX = 309; | ||
|
|
||
| /* Threshold to detect tiny values, as in section 8.2.1 of [1] */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments like this one pointing to specific places in the Schubfach paper are very helpful in understanding the constants and the various steps in the algorithm.
bplb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's time for this excellent work to advance.
|
@rgiulietti This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 381 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@turbanoff, @jddarcy, @bplb) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
|
/integrate |
|
@rgiulietti |
|
/sponsor |
|
Going to push as commit 72bcf2a.
Your commit was automatically rebased without conflicts. |
|
@jddarcy @rgiulietti Pushed as commit 72bcf2a. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
|
Hallelujah! |
|
@rgiulietti friendly ping, noob question: Do you believe some parts of the algorithm could exploit explicit SIMD instructions (via the high level Vector API) for even better performance (such as https://github.com/wrandelshofer/FastDoubleParser ) ? |
Hello,
here's a PR for a patch submitted on March 2020 1 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
Progress
Issues
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/3402/head:pull/3402$ git checkout pull/3402Update a local copy of the PR:
$ git checkout pull/3402$ git pull https://git.openjdk.java.net/jdk pull/3402/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 3402View PR using the GUI difftool:
$ git pr show -t 3402Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/3402.diff