Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #83528 > unrolled thread
| Started by | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| First post | 2022-04-08 15:40 +0300 |
| Last post | 2022-04-09 09:10 -0700 |
| Articles | 18 — 10 participants |
Back to article view | Back to comp.lang.c++
Adjusting printf() rounding Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-08 15:40 +0300
Re: Adjusting printf() rounding Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2022-04-08 06:02 -0700
Re: Adjusting printf() rounding Marcel Mueller <news.5.maazl@spamgourmet.org> - 2022-04-08 18:21 +0200
Re: Adjusting printf() rounding Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-08 19:38 +0300
Re: Adjusting printf() rounding Sams Lara <samlara622@gmail.com> - 2022-04-08 18:48 +0100
Re: Adjusting printf() rounding Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-08 23:44 +0300
Re: Adjusting printf() rounding Marcel Mueller <news.5.maazl@spamgourmet.org> - 2022-04-09 12:58 +0200
Re: Adjusting printf() rounding Geoff <geoff@invalid.invalid> - 2022-04-09 08:45 -0700
Re: Adjusting printf() rounding Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-04-09 13:05 -0700
Re: Adjusting printf() rounding red floyd <no.spam.here@its.invalid> - 2022-04-09 13:36 -0700
Re: Adjusting printf() rounding Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-09 16:08 -0700
Re: Adjusting printf() rounding Manfred <noname@add.invalid> - 2022-04-08 21:30 +0200
Re: Adjusting printf() rounding "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-04-09 10:11 +0200
Re: Adjusting printf() rounding Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-10 16:39 +0300
Re: Adjusting printf() rounding Sams Lara <samlara622@gmail.com> - 2022-04-10 18:36 +0100
Re: Adjusting printf() rounding Paavo Helde <eesnimi@osa.pri.ee> - 2022-04-10 21:50 +0300
Re: Adjusting printf() rounding Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-09 09:05 -0700
Re: Adjusting printf() rounding Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-04-09 09:10 -0700
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-04-08 15:40 +0300 |
| Subject | Adjusting printf() rounding |
| Message-ID | <t2pag0$eab$1@dont-email.me> |
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
TIA
Paavo
[toc] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2022-04-08 06:02 -0700 |
| Message-ID | <e6a0708c-30ac-4d4a-b91f-4423b715c280n@googlegroups.com> |
| In reply to | #83528 |
On Friday, 8 April 2022 at 13:40:47 UTC+1, 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).
>
printf() is used a lot for learner programs, and for debugging. There the results of
a floating point conversion are probably intended for human reading.
However in real production use, it's unlikely you'd want to display many floating
point number for humans to read. The output would mostly go for automatic
processing at a later stage. An example is paths in SVG files - these are
text, but they are primarily intended for parsers to read.
[toc] | [prev] | [next] | [standalone]
| From | Marcel Mueller <news.5.maazl@spamgourmet.org> |
|---|---|
| Date | 2022-04-08 18:21 +0200 |
| Message-ID | <t2pnek$3f5em$1@gwaiyur.mb-net.net> |
| In reply to | #83528 |
Am 08.04.22 um 14:40 schrieb Paavo Helde: > I can understand that rounding-to-even rule is good in mathematical > operations as it is statistically unbiased. ... if the values are evenly distributed. > However, with printf the > rounding appears in decimal, not in binary, and the result is meant There is no difference between decimal and binary representation with respect to rounding to integers since both number systems share the same prime factor 2. This also applies if you use fractional numbers because this is equivalent to a multiplication with a power of ten followed by an integer rounding. And if you run out of sufficient binary digits this typically happened before the rounding. > primarily for human consumption, not for statistics. It is not clear to > me these things should follow the same ideology, what do you think? For deterministic results floating point types are not appropriate. Applications that depend on this are broken by design. Whoever depends on deterministic fractional numbers should use decimal floats or fixed point numbers. > 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? Why should you care about that difference? If you have more complex calculations with floating point numbers not only the last digit is indeterminate. E.g. transcendental functions typically do not provide the maximum possible precision in many FPU implementations. And if you depend on a specific rounding mode you should use your own rounding with round/floor/ceil which have well defined behavior. Marcel
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-04-08 19:38 +0300 |
| Message-ID | <t2podd$ubk$1@dont-email.me> |
| In reply to | #83536 |
08.04.2022 19:21 Marcel Mueller kirjutas:
>> 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?
>
> Why should you care about that difference?
>
> If you have more complex calculations with floating point numbers not
> only the last digit is indeterminate. E.g. transcendental functions
> typically do not provide the maximum possible precision in many FPU
> implementations.
>
> And if you depend on a specific rounding mode you should use your own
> rounding with round/floor/ceil which have well defined behavior.
I'm not concerned about the last (16-th) digit at all. In this case, I'm
concerned about the third digit.
printf("%.3g\n", 212.5) yields 212 in Linux and 213 on Windows.
Even if we could swallow it ourselves, it would be hard to explain our
customers why our software works inconsistently cross platform.
[toc] | [prev] | [next] | [standalone]
| From | Sams Lara <samlara622@gmail.com> |
|---|---|
| Date | 2022-04-08 18:48 +0100 |
| Message-ID | <t2psnc$19rm$1@gioia.aioe.org> |
| In reply to | #83537 |
On 08/04/2022 17:38, Paavo Helde wrote:
>
> I'm not concerned about the last (16-th) digit at all. In this case,
> I'm concerned about the third digit.
>
> printf("%.3g\n", 212.5) yields 212 in Linux and 213 on Windows.
>
> Even if we could swallow it ourselves, it would be hard to explain our
> customers why our software works inconsistently cross platform.
I am getting 212 on Windows 11 as well 64 bit:
#include <stdio.h>
int main(void)
{
printf("%0.3g\n", 212.5);
printf("%0.3g\n", 213.5);
printf("%0.3g\n", 214.5);
printf("%0.3g\n", 215.5);
return 0;
/* Output in Windows 11 using Visual Studio 2022
212
214
214
216
*/
}
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-04-08 23:44 +0300 |
| Message-ID | <t2q6rp$kgd$1@dont-email.me> |
| In reply to | #83539 |
08.04.2022 20:48 Sams Lara kirjutas:
> On 08/04/2022 17:38, Paavo Helde wrote:
>>
>> I'm not concerned about the last (16-th) digit at all. In this case,
>> I'm concerned about the third digit.
>>
>> printf("%.3g\n", 212.5) yields 212 in Linux and 213 on Windows.
>>
>> Even if we could swallow it ourselves, it would be hard to explain our
>> customers why our software works inconsistently cross platform.
>
> I am getting 212 on Windows 11 as well 64 bit:
>
> #include <stdio.h>
>
> int main(void)
> {
> printf("%0.3g\n", 212.5);
> printf("%0.3g\n", 213.5);
> printf("%0.3g\n", 214.5);
> printf("%0.3g\n", 215.5);
>
> return 0;
>
> /* Output in Windows 11 using Visual Studio 2022
> 212
> 214
> 214
> 216
> */
> }
Yes, you are right, it looks like Windows/MSVC is in principle also
switching over to Banker's Rounding, but it seems there are some
combinations of OS and the MSVC compiler where this has not yet
happened. Probably I just need to give up and forget about the problem,
it will sort itself out in some years.
[toc] | [prev] | [next] | [standalone]
| From | Marcel Mueller <news.5.maazl@spamgourmet.org> |
|---|---|
| Date | 2022-04-09 12:58 +0200 |
| Message-ID | <t2ros9$3mkhv$1@gwaiyur.mb-net.net> |
| In reply to | #83542 |
Am 08.04.22 um 22:44 schrieb Paavo Helde: > Yes, you are right, it looks like Windows/MSVC is in principle also > switching over to Banker's Rounding, but it seems there are some > combinations of OS and the MSVC compiler where this has not yet > happened. The OS is probably not significant. The related code should be in in the C runtime, i.e. msvcrt*.dll. So basically it depends on the MSVC version. > Probably I just need to give up and forget about the problem, > it will sort itself out in some years. Or you just use another compiler. If your software is cross platform it should be straight forward to use e.g. gcc (or mingw) on Windows which will very likely behave the same as on other platforms since they all share the same glibc code. Marcel
[toc] | [prev] | [next] | [standalone]
| From | Geoff <geoff@invalid.invalid> |
|---|---|
| Date | 2022-04-09 08:45 -0700 |
| Message-ID | <gaa35h9b1tv4cd82gudk3l4h9eqttt7klj@4ax.com> |
| In reply to | #83545 |
On Sat, 9 Apr 2022 12:58:17 +0200, Marcel Mueller
<news.5.maazl@spamgourmet.org> wrote:
>Am 08.04.22 um 22:44 schrieb Paavo Helde:
>> Yes, you are right, it looks like Windows/MSVC is in principle also
>> switching over to Banker's Rounding, but it seems there are some
>> combinations of OS and the MSVC compiler where this has not yet
>> happened.
>
>The OS is probably not significant. The related code should be in in the
>C runtime, i.e. msvcrt*.dll. So basically it depends on the MSVC version.
>
>> Probably I just need to give up and forget about the problem,
>> it will sort itself out in some years.
>
>Or you just use another compiler. If your software is cross platform it
>should be straight forward to use e.g. gcc (or mingw) on Windows which
>will very likely behave the same as on other platforms since they all
>share the same glibc code.
>
>
>Marcel
Per the Microsoft Runtime Library Reference:
"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 exactly representable numbers. For example, 2.35 (which,
when represented in memory, is closer to 2.35000000000000008)
continues to round up to 2.4. Rounding done by these functions now
also respects the floating point rounding mode set by fesetround.
Previously, rounding always chose FE_TONEAREST behavior. This change
only affects programs built using Visual Studio 2019 version 16.2 and
later. To use the legacy floating point rounding behavior, link with
legacy_stdio_float_rounding.obj."
So, yes, it was OS-dependent but implemented in the MSVCRT library
supplied with Windows 10.
It's also very explicit about what you need to do to stop this
behavior.
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l?f1url=%3FappId%3DDev16IDEF1%26l%3DEN-US%26k%3Dk(STDIO%252Fprintf);k(printf);k(DevLang-C%252B%252B);k(TargetOS-Windows)%26rd%3Dtrue&view=msvc-170
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2022-04-09 13:05 -0700 |
| Message-ID | <87ilrinhss.fsf@nosuchdomain.example.com> |
| In reply to | #83545 |
Marcel Mueller <news.5.maazl@spamgourmet.org> writes:
> Am 08.04.22 um 22:44 schrieb Paavo Helde:
>> Yes, you are right, it looks like Windows/MSVC is in principle also
>> switching over to Banker's Rounding, but it seems there are some
>> combinations of OS and the MSVC compiler where this has not yet
>> happened.
>
> The OS is probably not significant. The related code should be in in
> the C runtime, i.e. msvcrt*.dll. So basically it depends on the MSVC
> version.
msvcrt.dll is used only by old versions of Microsoft Visual C++, from
4.2 to 6.0. More modern versions of MS Visual Studio use different
DLLs.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | red floyd <no.spam.here@its.invalid> |
|---|---|
| Date | 2022-04-09 13:36 -0700 |
| Message-ID | <t2sqpb$9li$1@redfloyd.dont-email.me> |
| In reply to | #83550 |
On 4/9/2022 1:05 PM, Keith Thompson wrote: > Marcel Mueller <news.5.maazl@spamgourmet.org> writes: >> Am 08.04.22 um 22:44 schrieb Paavo Helde: >>> Yes, you are right, it looks like Windows/MSVC is in principle also >>> switching over to Banker's Rounding, but it seems there are some >>> combinations of OS and the MSVC compiler where this has not yet >>> happened. >> >> The OS is probably not significant. The related code should be in in >> the C runtime, i.e. msvcrt*.dll. So basically it depends on the MSVC >> version. > > msvcrt.dll is used only by old versions of Microsoft Visual C++, from > 4.2 to 6.0. More modern versions of MS Visual Studio use different > DLLs. > Here's the details. https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2022-04-09 16:08 -0700 |
| Message-ID | <t2t3kv$aue$1@dont-email.me> |
| In reply to | #83545 |
On 4/9/2022 3:58 AM, Marcel Mueller wrote: > Am 08.04.22 um 22:44 schrieb Paavo Helde: >> Yes, you are right, it looks like Windows/MSVC is in principle also >> switching over to Banker's Rounding, but it seems there are some >> combinations of OS and the MSVC compiler where this has not yet happened. > > The OS is probably not significant. The related code should be in in the > C runtime, i.e. msvcrt*.dll. So basically it depends on the MSVC version. > It is true that the OS itself is not significant. But starting from some past version of MSVC the run-time library has been detached from the MSVC package and became part of an independently-installed and independently-updated WindowsSDK package. One can say that WindowsSDK is arguably closer associated with OS than with MSVC. -- Best regards, Andrey Tarasevich
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2022-04-08 21:30 +0200 |
| Message-ID | <t2q2ge$1vn6$1@gioia.aioe.org> |
| In reply to | #83528 |
On 4/8/2022 2:40 PM, 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 few suggestions:
1) implement your own rounding routine.
2) use static linking - the dependency on Windows version (Windows 10
version 2004 as you mention) means a dependency on the version of one of
the successors of msvcrt.dll. You should get rid of this runtime
dependency by linking in the static C runtime library. This means that
if your application is linked with the Banker's version of the runtime
it should use that rounding on any Windows version. Cross-consistency
between Linux and Windows might be trickier, though.
3) depending on the nature of data, this might be just optics:
If it's data representing physical quantities, then 2.5 might just as
well come in as 2.4999999999 or 2.5000000001, and the chance of getting
exactly 2.5 is negligible, while on the other hand rounded numbers are
grossly inexact by definition.
If it's data where 2.5 has some significant probability (e.g. monetary
quantities) then probably even option 1 is easy enough.
HTH.
>
> A demo program:
>
> $ cat test6.cpp
> #include <cstdio>
> int main() {
> std::printf("%.3g\n", 212.5);
> }
> $ g++ test6.cpp
> $ ./a.out
> 212
>
>
>
>
> TIA
> Paavo
[toc] | [prev] | [next] | [standalone]
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-04-09 10:11 +0200 |
| Message-ID | <t2rf2n$gmj$1@dont-email.me> |
| In reply to | #83528 |
On 8 Apr 2022 14: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
>
>
>
>
> TIA
> Paavo
I haven't used Dragonbox but apparently you can specify the rounding
policy, so you could write something on top that has the default you
want -- or just use the default round-to-even on all systems.
https://github.com/jk-jeon/dragonbox
- Alf
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-04-10 16:39 +0300 |
| Message-ID | <t2umn3$suj$1@dont-email.me> |
| In reply to | #83543 |
09.04.2022 11:11 Alf P. Steinbach kirjutas: > > I haven't used Dragonbox but apparently you can specify the rounding > policy, so you could write something on top that has the default you > want -- or just use the default round-to-even on all systems. > > https://github.com/jk-jeon/dragonbox Thanks for the reply, it appears indeed the best approach is to use an alternative library like Dragonbox or Google's double_conversion. These libraries also have the advantage of not depending on the locale, making them both faster and more robust than the standard sprintf().
[toc] | [prev] | [next] | [standalone]
| From | Sams Lara <samlara622@gmail.com> |
|---|---|
| Date | 2022-04-10 18:36 +0100 |
| Message-ID | <t2v4q5$1srj$1@gioia.aioe.org> |
| In reply to | #83561 |
On 10/04/2022 14:39, Paavo Helde wrote:
>
> Thanks for the reply, it appears indeed the best approach is to use an
> alternative library like Dragonbox or Google's double_conversion.
>
> These libraries also have the advantage of not depending on the
> locale, making them both faster and more robust than the standard
> sprintf().
I think the best approach is to use this small function:
float RoundCustom(float ValueToRound)
{
return (floorf(ValueToRound + 0.5));
}
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <eesnimi@osa.pri.ee> |
|---|---|
| Date | 2022-04-10 21:50 +0300 |
| Message-ID | <t2v8u1$ica$1@dont-email.me> |
| In reply to | #83562 |
10.04.2022 20:36 Sams Lara kirjutas:
> On 10/04/2022 14:39, Paavo Helde wrote:
>>
>> Thanks for the reply, it appears indeed the best approach is to use an
>> alternative library like Dragonbox or Google's double_conversion.
>>
>> These libraries also have the advantage of not depending on the
>> locale, making them both faster and more robust than the standard
>> sprintf().
>
>
> I think the best approach is to use this small function:
>
> float RoundCustom(float ValueToRound)
> {
> return (floorf(ValueToRound + 0.5));
> }
Sure, this would work fine if my task would be rounding to integers.
Unfortunately, it's not (rather, it is about implementing an equivalent
of sprintf() in a cross-platform interpreted script language).
Cheers
Paavo
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2022-04-09 09:05 -0700 |
| Message-ID | <t2sarf$7g9$1@dont-email.me> |
| In reply to | #83528 |
On 4/8/2022 5:40 AM, Paavo Helde wrote:
>
> 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.
>
Technically, it is no longer a promise of MSVC, but rather a promise of
Windows SDK. However, it is run-time controllable through such internal
SDK options as
_CRT_INTERNAL_PRINTF_STANDARD_ROUNDING
and apparently different versions of MSVC set different initial settings
in the program's startup code, since the same version of SDK produces
different results in different versions of MSVC.
#include <cstdio>
int main()
{
std::printf("%.3g\n", 212.5);
*__local_stdio_printf_options() |=
_CRT_INTERNAL_PRINTF_STANDARD_ROUNDING;
std::printf("%.3g\n", 212.5);
*__local_stdio_printf_options() &=
~_CRT_INTERNAL_PRINTF_STANDARD_ROUNDING;
std::printf("%.3g\n", 212.5);
}
Visual Studio 2017
213
212
213
Visual Studio 2019
212
212
213
--
Best regards,
Andrey Tarasevich
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2022-04-09 09:10 -0700 |
| Message-ID | <t2sb6d$as9$1@dont-email.me> |
| In reply to | #83546 |
On 4/9/2022 9:05 AM, Andrey Tarasevich wrote:
> On 4/8/2022 5:40 AM, Paavo Helde wrote:
>>
>> 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.
>>
>
> Technically, it is no longer a promise of MSVC, but rather a promise of
> Windows SDK. However, it is run-time controllable through such internal
> SDK options as
>
> _CRT_INTERNAL_PRINTF_STANDARD_ROUNDING
>
> and apparently different versions of MSVC set different initial settings
> in the program's startup code, since the same version of SDK produces
> different results in different versions of MSVC.
>
Also, once you enable
_CRT_INTERNAL_PRINTF_STANDARD_ROUNDING
`printf` in MSVC begins to obey the rounding modes set by `fesetround`
#include <cstdio>
#include <cfenv>
int main()
{
*__local_stdio_printf_options() |=
_CRT_INTERNAL_PRINTF_STANDARD_ROUNDING;
std::printf("%.3g\n", 212.5);
std::fesetround(FE_UPWARD);
std::printf("%.3g\n", 212.5);
std::fesetround(FE_DOWNWARD);
std::printf("%.3g\n", 212.5);
std::fesetround(FE_TONEAREST);
std::printf("%.3g\n", 212.5);
}
212
213
212
212
--
Best regards,
Andrey Tarasevich
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web