-
Notifications
You must be signed in to change notification settings - Fork 10.4k
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
Updates to #15474 Floating-point printing code (SwiftDtoa.cpp) #16178
Merged
tbkka
merged 1 commit into
swiftlang:master
from
tbkka:tbkka-floating-point-printing-update
Apr 26, 2018
Merged
Updates to #15474 Floating-point printing code (SwiftDtoa.cpp) #16178
tbkka
merged 1 commit into
swiftlang:master
from
tbkka:tbkka-floating-point-printing-update
Apr 26, 2018
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This collects a number of changes I've been testing over the last month. * Bug fix: The single-precision float formatter did not always round the last digit even in cases where there were two possible outputs that were otherwise equally good. * Algorithm simplification: The condition for determining whether to widen or narrow the interval was more complex than necessary. I now simply widen the interval for all even significands. * Code simplification: The single-precision float formatter now uses fewer 64-bit features. This eliminated some 32-bit vs. 64-bit conditionals in exchange for a minor loss of performance (~2%). * Minor performance tweaks: Steve Canon pointed out a few places where I could avoid some extraneous arithmetic. I've also rewritten a lot of comments to try to make the exposition clearer. The earlier testing regime focused on testing from first principles. For example, I verified accuracy by feeding the result back into the C library `strtof`, `strtod`, etc. and checking round-trip exactness. Unfortunately, this approach requires many checks for each value, limiting test performance. It's also difficult to validate last-digit rounding. For this round of updates, I've instead compared the digit decompositions to other popular algorithms: * David M. Gay's gdtoa library is a robust and well-tested implementation based on Dragon4. It supports all formats, but is slow. (netlib.org/fp) * Grisu3 supports Float and Double. It is fast but incomplete, failing on about 1% of all inputs. (github.com/google/double-conversion) * Errol4 is fast and complete but only supports Double. The repository includes an implementation of the enumeration algorithm described in the Errol paper. (github.com/marcandrysco/errol) The exact tests varied by format: * Float: SwiftDtoa now generates the exact same digits as gdtoa for every single-precision Float. * Double: Testing against Grisu3 (with fallback to Errol4 when Grisu3 failed) greatly improved test performance. This allowed me to test 100 trillion (10^14) randomly-selected doubles in a reasonable amount of time. I also checked all values generated by the Errol enumeration algorithm. * Float80: I compared the Float80 output to the gdtoa library because neither Grisu3 nor Errol4 yet supports 80-bit extended precision. All values generated by the Errol enumeration algorithm have been checked, as well as several billion randomly-selected values.
@swift-ci Please benchmark |
@swift-ci Please test |
stephentyrone
approved these changes
Apr 26, 2018
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.
Looks good.
!!! Couldn't read commit file !!! |
stephentyrone
pushed a commit
that referenced
this pull request
Apr 27, 2018
This collects a number of changes I've been testing over the last month. * Bug fix: The single-precision float formatter did not always round the last digit even in cases where there were two possible outputs that were otherwise equally good. * Algorithm simplification: The condition for determining whether to widen or narrow the interval was more complex than necessary. I now simply widen the interval for all even significands. * Code simplification: The single-precision float formatter now uses fewer 64-bit features. This eliminated some 32-bit vs. 64-bit conditionals in exchange for a minor loss of performance (~2%). * Minor performance tweaks: Steve Canon pointed out a few places where I could avoid some extraneous arithmetic. I've also rewritten a lot of comments to try to make the exposition clearer. The earlier testing regime focused on testing from first principles. For example, I verified accuracy by feeding the result back into the C library `strtof`, `strtod`, etc. and checking round-trip exactness. Unfortunately, this approach requires many checks for each value, limiting test performance. It's also difficult to validate last-digit rounding. For this round of updates, I've instead compared the digit decompositions to other popular algorithms: * David M. Gay's gdtoa library is a robust and well-tested implementation based on Dragon4. It supports all formats, but is slow. (netlib.org/fp) * Grisu3 supports Float and Double. It is fast but incomplete, failing on about 1% of all inputs. (github.com/google/double-conversion) * Errol4 is fast and complete but only supports Double. The repository includes an implementation of the enumeration algorithm described in the Errol paper. (github.com/marcandrysco/errol) The exact tests varied by format: * Float: SwiftDtoa now generates the exact same digits as gdtoa for every single-precision Float. * Double: Testing against Grisu3 (with fallback to Errol4 when Grisu3 failed) greatly improved test performance. This allowed me to test 100 trillion (10^14) randomly-selected doubles in a reasonable amount of time. I also checked all values generated by the Errol enumeration algorithm. * Float80: I compared the Float80 output to the gdtoa library because neither Grisu3 nor Errol4 yet supports 80-bit extended precision. All values generated by the Errol enumeration algorithm have been checked, as well as several billion randomly-selected values.
airspeedswift
pushed a commit
that referenced
this pull request
May 7, 2018
) This collects a number of changes I've been testing over the last month. * Bug fix: The single-precision float formatter did not always round the last digit even in cases where there were two possible outputs that were otherwise equally good. * Algorithm simplification: The condition for determining whether to widen or narrow the interval was more complex than necessary. I now simply widen the interval for all even significands. * Code simplification: The single-precision float formatter now uses fewer 64-bit features. This eliminated some 32-bit vs. 64-bit conditionals in exchange for a minor loss of performance (~2%). * Minor performance tweaks: Steve Canon pointed out a few places where I could avoid some extraneous arithmetic. I've also rewritten a lot of comments to try to make the exposition clearer. The earlier testing regime focused on testing from first principles. For example, I verified accuracy by feeding the result back into the C library `strtof`, `strtod`, etc. and checking round-trip exactness. Unfortunately, this approach requires many checks for each value, limiting test performance. It's also difficult to validate last-digit rounding. For this round of updates, I've instead compared the digit decompositions to other popular algorithms: * David M. Gay's gdtoa library is a robust and well-tested implementation based on Dragon4. It supports all formats, but is slow. (netlib.org/fp) * Grisu3 supports Float and Double. It is fast but incomplete, failing on about 1% of all inputs. (github.com/google/double-conversion) * Errol4 is fast and complete but only supports Double. The repository includes an implementation of the enumeration algorithm described in the Errol paper. (github.com/marcandrysco/errol) The exact tests varied by format: * Float: SwiftDtoa now generates the exact same digits as gdtoa for every single-precision Float. * Double: Testing against Grisu3 (with fallback to Errol4 when Grisu3 failed) greatly improved test performance. This allowed me to test 100 trillion (10^14) randomly-selected doubles in a reasonable amount of time. I also checked all values generated by the Errol enumeration algorithm. * Float80: I compared the Float80 output to the gdtoa library because neither Grisu3 nor Errol4 yet supports 80-bit extended precision. All values generated by the Errol enumeration algorithm have been checked, as well as several billion randomly-selected values.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Updates to #15474: This collects a number of changes I've been testing over the
last month.
Changes
Bug fix: The single-precision float formatter sometimes
chose an odd final digit when there was an equally-good
even choice.
Algorithm simplification: The condition for determining
whether to widen or narrow the interval was more complex than
necessary. I now simply widen the interval for all even
significands.
Code simplification: I've simplified the single-precision float formatter.
Eliminating some 32-bit vs. 64-bit conditionals simplified the code in
exchange for a minor loss of performance (~2%). A simpler power-of-10
calculation allows more error in that step but does not affect the result.
Performance tweaks: Steve Canon pointed out a few places
where I could avoid some extraneous arithmetic.
I've also rewritten a lot of comments to try to make the exposition
clearer.
Testing Approach
The earlier testing regime focused on testing from first
principles. For example, I verified accuracy by feeding the
result back into the C library
strtof
,strtod
, etc. andchecking round-trip exactness. Unfortunately, this approach
requires many checks for each value, limiting test performance.
It's also difficult to validate last-digit rounding.
For this round of updates, I've instead compared the digit
decompositions to other popular algorithms:
implementation based on Dragon4. It supports all formats, but
is slow. (netlib.org/fp)
failing on about 1% of all inputs.
(github.com/google/double-conversion)
repository includes an implementation of the enumeration
algorithm described in the Errol paper.
(github.com/marcandrysco/errol)
Test Details
The exact tests varied by format:
Float: SwiftDtoa now generates the same digits as gdtoa's
mode 0 for every single-precision Float.
Double: Testing against Grisu3 (with fallback to Errol4 when
Grisu3 failed) greatly improved test performance. This
allowed me to test 100 trillion (10^14) randomly-selected
doubles in a reasonable amount of time. I also checked all
values generated by the Errol enumeration algorithm.
Float80: I compared the Float80 output to the gdtoa library
because neither Grisu3 nor Errol4 yet supports 80-bit extended
precision. All values generated by the Errol enumeration
algorithm have been checked, as well as several billion
randomly-selected values.