diff options
author | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2020-05-10 22:43:09 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-05-11 10:52:24 +0200 |
commit | bc5d5bf75d06c422094a3bd0aafd14be8a84c61a (patch) | |
tree | 9801ecad6fc9ac2ca6230c992a56a5371ae6f45b /Libraries/LibC/memory.h | |
parent | c19d5943f14fe5bf39b885e58ec6d1df2649a07b (diff) | |
download | serenity-bc5d5bf75d06c422094a3bd0aafd14be8a84c61a.zip |
LibC: Implement new strtod, accurate up to 8 eps
This strtod implementation is not perfectly accurate, as evidenced by the test
(accuracy_strtod.cpp), but it is sufficiently close (up to 8 eps).
The main sources of inaccuracy are:
- Highly repeated division/multiplication by 'base'
(Each operation brings a multiplicative error of 1+2^-53.)
- Loss during the initial conversion from long long to double (most prominently,
69294956446009195 should first be rounded to 69294956446009200 and then
converted to 69294956446009200.0 and then divided by ten, yielding
6929495644600920.0. Currently, it converts first to double, can't represent
69294956446009195.0, and instead represents 69294956446009190, which
eventually yields 6929495644600919.0. Close, but technically wrong.)
I believe that these issues can be fixed by rewriting the part at and after
double value = digits.number();
and that the loss before that is acceptable.
Specifically, losing the exact exponent on overflow is obviously fine.
The only other loss occurs when the significant digits overflow a 'long long'.
But these store 64(-7ish) bits, and the mantissa of a double only stores 52 bits.
With a bit more thinking, one could probably get the error down to 1 or 2 eps.
(But not better.)
Fixes #1979.
Diffstat (limited to 'Libraries/LibC/memory.h')
0 files changed, 0 insertions, 0 deletions