public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest
@ 2022-10-31 11:23 jakub at gcc dot gnu.org
2022-11-01 13:57 ` [Bug libstdc++/107468] " ppalka at gcc dot gnu.org
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-10-31 11:23 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107468
Bug ID: 107468
Summary: std::from_chars doesn't always round to nearest
Product: gcc
Version: 13.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
#include <cfenv>
#include <charconv>
#include <iostream>
#include <string_view>
int
main()
{
float f;
char buf[] = "3.355447e+07";
fesetround(FE_DOWNWARD);
auto [ptr, ec] = std::from_chars(buf, buf + sizeof (buf) - 1, f,
std::chars_format::scientific);
char buf2[128];
auto [ptr2, ec2] = std::to_chars(buf2, buf2 + 128, f,
std::chars_format::fixed);
std::cout << std::string_view(buf2, ptr2 - buf2) << std::endl;
}
33554470 isn't representable in IEEE single, only 33554468 and 33554472 are,
the former is 0x1.000012p+25 and the latter is 0x1.000014p+25 and the latter
has
0 as the least significant digit. So, round to even should be 33554472 and
that is what happens without the fesetround(FE_DOWNWARD).
When fast_float isn't used, floating_from_chars.cc temporarily overrides the
rounding to nearest, but when it is used, it doesn't.
In most cases it is fine, because fast_float usually computes the mantissa and
exponent in integral code. But it has two exceptions for this I think.
One is the fast path:
// Next is Clinger's fast path.
if (binary_format<T>::min_exponent_fast_path() <= pns.exponent &&
pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa
<=binary_format<T>::max_mantissa_fast_p
ath() && !pns.too_many_digits) {
value = T(pns.mantissa);
if (pns.exponent < 0) { value = value /
binary_format<T>::exact_power_of_ten(-pns.exponent); }
else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent);
}
if (pns.negative) { value = -value; }
return answer;
}
I'm afraid we need to temporarily override rounding to nearest around the
multiplications in there. And the other one is:
T b;
to_float(false, am_b, b);
adjusted_mantissa theor = to_extended_halfway(b);
where I think we don't really need it but I don't understand the point of
jumping through the floating point format, it encodes am_b into an integer,
memcpys it to float/double (in to_float), then immediately memcpys it back to
an integer (in to_extended called from to_extended_halfway) and then unpacks it
with some adjustments.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/107468] std::from_chars doesn't always round to nearest
2022-10-31 11:23 [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest jakub at gcc dot gnu.org
@ 2022-11-01 13:57 ` ppalka at gcc dot gnu.org
2022-11-01 20:17 ` ppalka at gcc dot gnu.org
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: ppalka at gcc dot gnu.org @ 2022-11-01 13:57 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107468
Patrick Palka <ppalka at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
Last reconfirmed| |2022-11-01
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/107468] std::from_chars doesn't always round to nearest
2022-10-31 11:23 [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest jakub at gcc dot gnu.org
2022-11-01 13:57 ` [Bug libstdc++/107468] " ppalka at gcc dot gnu.org
@ 2022-11-01 20:17 ` ppalka at gcc dot gnu.org
2022-11-07 14:17 ` cvs-commit at gcc dot gnu.org
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: ppalka at gcc dot gnu.org @ 2022-11-01 20:17 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107468
--- Comment #1 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Might be good to let upstream know about these issues
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/107468] std::from_chars doesn't always round to nearest
2022-10-31 11:23 [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest jakub at gcc dot gnu.org
2022-11-01 13:57 ` [Bug libstdc++/107468] " ppalka at gcc dot gnu.org
2022-11-01 20:17 ` ppalka at gcc dot gnu.org
@ 2022-11-07 14:17 ` cvs-commit at gcc dot gnu.org
2022-11-07 14:20 ` jakub at gcc dot gnu.org
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-11-07 14:17 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107468
--- Comment #2 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:cb0ceeaee9e041aaac3edd089b07b439621d0f29
commit r13-3755-gcb0ceeaee9e041aaac3edd089b07b439621d0f29
Author: Jakub Jelinek <jakub@redhat.com>
Date: Mon Nov 7 15:17:21 2022 +0100
libstdc++: Update from latest fast_float [PR107468]
The following patch updates from fast_float trunk. That way
it grabs two of the 4 LOCAL_PATCHES, some smaller tweaks, to_extended
cleanups and most importantly fix for the incorrect rounding case,
PR107468 aka https://github.com/fastfloat/fast_float/issues/149
Using std::fegetround showed in benchmarks too slow, so instead of
doing that the patch limits the fast path where it uses floating
point multiplication rather than integral to cases where we can
prove there will be no rounding (the multiplication will be exact, not
just that the two multiplication or division operation arguments are
exactly representable).
2022-11-07 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/107468
* src/c++17/fast_float/MERGE: Adjust for merge from upstream.
* src/c++17/fast_float/LOCAL_PATCHES: Remove commits that were
upstreamed.
* src/c++17/fast_float/README.md: Merge from fast_float
662497742fea7055f0e0ee27e5a7ddc382c2c38e commit.
* src/c++17/fast_float/fast_float.h: Likewise.
* testsuite/20_util/from_chars/pr107468.cc: New test.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/107468] std::from_chars doesn't always round to nearest
2022-10-31 11:23 [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest jakub at gcc dot gnu.org
` (2 preceding siblings ...)
2022-11-07 14:17 ` cvs-commit at gcc dot gnu.org
@ 2022-11-07 14:20 ` jakub at gcc dot gnu.org
2022-11-07 16:53 ` redi at gcc dot gnu.org
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: jakub at gcc dot gnu.org @ 2022-11-07 14:20 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107468
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Fixed now on the trunk.
Dunno what to do for GCC 12, nothing, or do a limited backport (just the
Clinger's fast path related changes), something else?
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/107468] std::from_chars doesn't always round to nearest
2022-10-31 11:23 [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest jakub at gcc dot gnu.org
` (3 preceding siblings ...)
2022-11-07 14:20 ` jakub at gcc dot gnu.org
@ 2022-11-07 16:53 ` redi at gcc dot gnu.org
2022-11-24 9:39 ` cvs-commit at gcc dot gnu.org
2023-02-10 17:46 ` cvs-commit at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2022-11-07 16:53 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107468
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
The limited backport would be good, I don't think we need to backport the trunk
sync though.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/107468] std::from_chars doesn't always round to nearest
2022-10-31 11:23 [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest jakub at gcc dot gnu.org
` (4 preceding siblings ...)
2022-11-07 16:53 ` redi at gcc dot gnu.org
@ 2022-11-24 9:39 ` cvs-commit at gcc dot gnu.org
2023-02-10 17:46 ` cvs-commit at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2022-11-24 9:39 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107468
--- Comment #5 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:ec73b55c75baa16c1cf7482fa65928a8d45598d4
commit r13-4285-gec73b55c75baa16c1cf7482fa65928a8d45598d4
Author: Jakub Jelinek <jakub@redhat.com>
Date: Thu Nov 24 10:38:42 2022 +0100
libstdc++: Another merge from fast_float upstream [PR107468]
Upstream fast_float came up with a cheaper test for
fegetround () == FE_TONEAREST using one float addition, one subtraction
and one comparison. If we know we are rounding to nearest, we can use
fast path in more cases as before.
The following patch merges those changes into libstdc++.
2022-11-24 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/107468
* src/c++17/fast_float/MERGE: Adjust for merge from upstream.
* src/c++17/fast_float/fast_float.h: Merge from fast_float
2ef9abbcf6a11958b6fa685a89d0150022e82e78 commit.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Bug libstdc++/107468] std::from_chars doesn't always round to nearest
2022-10-31 11:23 [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest jakub at gcc dot gnu.org
` (5 preceding siblings ...)
2022-11-24 9:39 ` cvs-commit at gcc dot gnu.org
@ 2023-02-10 17:46 ` cvs-commit at gcc dot gnu.org
6 siblings, 0 replies; 8+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2023-02-10 17:46 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107468
--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-12 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:0061c84d2d85ca4c2ceca6116937f2d1fab6e10a
commit r12-9154-g0061c84d2d85ca4c2ceca6116937f2d1fab6e10a
Author: Jakub Jelinek <jakub@redhat.com>
Date: Mon Nov 7 15:17:21 2022 +0100
libstdc++: Update from latest fast_float [PR107468]
The following patch partially updates from fast_float trunk.
That way it gets fix for the incorrect rounding case,
PR107468 aka https://github.com/fastfloat/fast_float/issues/149
Using std::fegetround showed in benchmarks too slow, so instead of
doing that the patch limits the fast path where it uses floating
point multiplication rather than integral to cases where we can
prove there will be no rounding (the multiplication will be exact, not
just that the two multiplication or division operation arguments are
exactly representable).
2022-11-07 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/107468
* src/c++17/fast_float/fast_float.h: Partial merge from fast_float
662497742fea7055f0e0ee27e5a7ddc382c2c38e commit.
* testsuite/20_util/from_chars/pr107468.cc: New test.
(cherry picked from commit cb0ceeaee9e041aaac3edd089b07b439621d0f29)
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-02-10 17:46 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-31 11:23 [Bug libstdc++/107468] New: std::from_chars doesn't always round to nearest jakub at gcc dot gnu.org
2022-11-01 13:57 ` [Bug libstdc++/107468] " ppalka at gcc dot gnu.org
2022-11-01 20:17 ` ppalka at gcc dot gnu.org
2022-11-07 14:17 ` cvs-commit at gcc dot gnu.org
2022-11-07 14:20 ` jakub at gcc dot gnu.org
2022-11-07 16:53 ` redi at gcc dot gnu.org
2022-11-24 9:39 ` cvs-commit at gcc dot gnu.org
2023-02-10 17:46 ` cvs-commit at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).