Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #165576 > unrolled thread
| Started by | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| First post | 2022-04-08 12:15 -0400 |
| Last post | 2022-04-09 20:51 -0700 |
| Articles | 3 — 3 participants |
Back to article view | Back to comp.lang.c
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: Adjusting printf() rounding James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-04-08 12:15 -0400
Re: Adjusting printf() rounding Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-09 09:28 -0700
Re: Adjusting printf() rounding "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2022-04-09 20:51 -0700
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-04-08 12:15 -0400 |
| Subject | Re: Adjusting printf() rounding |
| Message-ID | <t2pn31$jkc$1@dont-email.me> |
On 4/8/22 08:40, Paavo Helde wrote:
>
> To be honest, this is a bit off-topic for C++, but maybe you guys have
> some insight here.
>
> This is an excerpt from
> "https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l?view=msvc-170"
>
> "Starting in Windows 10 version 2004 (build 19041), the printf family
> of functions prints exactly representable floating point numbers
> according to the IEEE 754 rules for rounding. In previous versions of
> Windows, exactly representable floating point numbers ending in '5'
> would always round up. IEEE 754 states that they must round to the
> closest even digit (also known as "Banker's Rounding"). For example,
> both printf("%1.0f", 1.5) and printf("%1.0f", 2.5) should round to 2.
> Previously, 1.5 would round to 2 and 2.5 would round to 3. [...] This
> change only affects programs built using Visual Studio 2019 version
> 16.2 and later."
>
> glibc has similar page and similar rules, though they do not speak
> about printf or iostream directly:
> "https://www.gnu.org/software/libc/manual/html_node/Rounding.html"
>
> I can understand that rounding-to-even rule is good in mathematical
> operations as it is statistically unbiased. However, with printf the
> rounding appears in decimal, not in binary, and the result is meant
> primarily for human consumption, not for statistics. It is not clear
> to me these things should follow the same ideology, what do you think?
>
> What's worse, it appears MSVC have not kept the promises which they
> made, and have reverted back to pre-MSVC19 behavior in VS2019 Update
> 11 (_MSC_VER==1929), rounding ties now up again.
>
> For me this means we have nasty cross-platform differences which we
> would rather try to avoid. How could we coerce glibc() to round up, or
> failing that, coerce MSVC to round down? I was thinking about adding
> or subtracting one ULP to the number beforehand, but this would surely
> ruin some other outputs (in my program I have no control over the
> numbers or precisions, these come from outside).
>
> A demo program:
>
> $ cat test6.cpp
> #include <cstdio>
> int main() {
> std::printf("%.3g\n", 212.5);
> }
> $ g++ test6.cpp
> $ ./a.out
> 212
I know nothing MSVC-specific, but I can tell you what the C standard
requires:
When printing floating point numbers, the *printf*() family is supposed
to obey the current rounding direction.
<fenv.h> defines macros for rounding directions. A given macro is
defined if and only if the implementation supports that rounding
direction. The standard describes 5 rounding modes, implementations are
allowed to add to that list.
#pragma STDC FENV_ROUND
May be used to set the rounding direction. One option is FE_DYNAMIC,
which allows the rounding direction to be changed by calls to
fesetround(). Be sure to check the return value from fesetround() - it's
not required to succeed.
If this worries you, it might be a good idea to use one of the new
decimal floating point types: _Decimal32, _Decimal64, or _Decimal128, if
your implementation supports them. The decimal floating point types have
their own equivalents of all the rounding direction features I described
above. The decimal floating point rounding direction need not be the
same as the regular floating point types.
[toc] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-04-09 09:28 -0700 |
| Message-ID | <86ilri9q6q.fsf@linuxsc.com> |
| In reply to | #165576 |
James Kuyper <jameskuyper@alumni.caltech.edu> writes:
> On 4/8/22 08:40, Paavo Helde wrote:
>
>> To be honest, this is a bit off-topic for C++, but maybe you guys
>> have some insight here.
>>
>> [.. behavior of rounding on floating-point output ..]
>>
>> A demo program:
>>
>> $ cat test6.cpp
>> #include <cstdio>
>> int main() {
>> std::printf("%.3g\n", 212.5);
>> }
>> $ g++ test6.cpp
>> $ ./a.out
>> 212
>
> I know nothing MSVC-specific, but I can tell you what the C
> standard requires:
>
> When printing floating point numbers, the *printf*() family is
> supposed to obey the current rounding direction.
> [.. discussion of rounding modes and how to set them ..]
I believe this assertion is an overstatement. Although there are
certain cases where the C standard does mandate correct rounding
(which implies using the current rounding direction), AFAICT
there is no general requirement that all *printf() floating-point
conversions be correctly rounded, or that they obey the current
rounding direction. Note that some statements are made about
rounding (both correct rounding and current rounding direction)
under a "Recommended practice" heading, but these statements are
only recommendations, not requirements.
[toc] | [prev] | [next] | [standalone]
| From | "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-04-09 20:51 -0700 |
| Message-ID | <61a0874c-6851-400d-bd03-9ba116801c75n@googlegroups.com> |
| In reply to | #165594 |
On Saturday, April 9, 2022 at 12:28:43 PM UTC-4, Tim Rentsch wrote:
> James Kuyper <james...@alumni.caltech.edu> writes:
>
> > On 4/8/22 08:40, Paavo Helde wrote:
> >
> >> To be honest, this is a bit off-topic for C++, but maybe you guys
> >> have some insight here.
> >>
> >> [.. behavior of rounding on floating-point output ..]
> >>
> >> A demo program:
> >>
> >> $ cat test6.cpp
> >> #include <cstdio>
> >> int main() {
> >> std::printf("%.3g\n", 212.5);
> >> }
> >> $ g++ test6.cpp
> >> $ ./a.out
> >> 212
> >
> > I know nothing MSVC-specific, but I can tell you what the C
> > standard requires:
> >
> > When printing floating point numbers, the *printf*() family is
> > supposed to obey the current rounding direction.
> > [.. discussion of rounding modes and how to set them ..]
>
> I believe this assertion is an overstatement. Although there are
> certain cases where the C standard does mandate correct rounding
> (which implies using the current rounding direction), AFAICT
> there is no general requirement that all *printf() floating-point
> conversions be correctly rounded,
That is quite correct.
"The accuracy of the floating-point operations ( + , - , * , / ) and of the
library functions in <math.h> and <complex.h> that return floating-
point results is implementation-defined, as is the accuracy of the
conversion between floating-point internal representations and
string representations performed by the library functions in
<stdio.h> , <stdlib.h> , and <wchar.h> . The implementation may
state that the accuracy is unknown." (5.2.2.4.2p8).
As a result of what the standard fails to mandate about the
accuracy of floating point operations, a fully conforming
implementation need not implement floating point in any useful
fashion. In particular, a conforming implementation of
printf("%g", LDBL_MAX) could perform the conversion between
internal and string representations so inaccurately that the result
would be -LDBL_MAX, so long as it's documentation says that it's
that inaccurate, or even merely says "the accuracy is unknown".
> ... or that they obey the current
> rounding direction. Note that some statements are made about
> rounding (both correct rounding and current rounding direction)
> under a "Recommended practice" heading, but these statements are
> only recommendations, not requirements.
That's why I used "supposed" rather than "required".
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web