Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re: sprintf rounding convention

by Joost (Canon)
on Oct 30, 2009 at 19:22 UTC ( #804207=note: print w/ replies, xml ) Need Help??


in reply to sprintf rounding convention

"Normal rounding" is a misleading term. As far as I know (and I can't be bothered to look it up) sprintf rounding uses whatever rounding libc uses, which tends but isn't guaranteed to be "banker's rounding". Banker's rounding, or HALF_EVEN in Java parlance*, is useful because it tends to lead to less distortion over large sums while still being predictable.

* HALF_EVEN is also the strategy Java uses for float and double maths.


Comment on Re: sprintf rounding convention
Re^2: sprintf rounding convention
by ikegami (Pope) on Oct 30, 2009 at 22:04 UTC
    That's incorrect. %f and other floating point specifiers always round to even. From F0convert:
    nv += 0.5; uv = (UV)nv; if (uv & 1 && uv == nv) uv--; /* Round to even */

    (There are paths I didn't take the time to understand, so maybe it doesn't always get to this function.)

      Now I'm confused:

      $ perl -v This is perl, v5.8.8 built for x86_64-linux-gnu-thread-multi $ perl -e 'printf "%.2f\n%.2f\n", 0.335, 1.335;' 0.34 1.33

      and

      C:\>perl -v This is perl, v5.8.9 built for MSWin32-x86-multi-thread (with 9 registered patches, see perl -V for more detail) C:\>perl -e "printf qq{%.2f\n%.2f\n}, 0.335, 1.335;" 0.34 1.34

      Am I missing something (as usual)?

      Update:

      Following ikegami's suggestion, I tried increasing the precision to 40 digits, and got:

      $ perl -v This is perl, v5.8.8 built for x86_64-linux-gnu-thread-multi $ perl -e 'printf "%.40f\n%.40f\n", 0.335, 1.335;' 0.3350000000000000199840144432528177276254 1.3349999999999999644728632119949907064438 C:\>perl -v This is perl, v5.8.9 built for MSWin32-x86-multi-thread (with 9 registered patches, see perl -V for more detail) C:\>perl -e "printf qq{%.40f\n%.40f\n}, 0.335, 1.335;" 0.3350000000000000200000000000000000000000 1.3350000000000000000000000000000000000000

      It looks like this variation is just an artifact of 64-bit vs. 32-bit, emphasizing how you should never rely on precise results from rounding.

        I bet perl -e'printf "%.40e\n", 0.335' gives 0.334999... on the system that rounded to 1.33. Let me know if not.

      Hmm... Then I think the sprintf documentation is incorrect, or possibly just confusing: (emphasis mine)
      Perl does its own "sprintf" formatting--it emulates the C function "sprintf", but it doesn't use it (except for floating- point numbers, and even then only the standard modifiers are allowed). As a result, any non-standard extensions in your local "sprintf" are not available from Perl.
        And what's incorrect about that? Perl prefers the "nearest even round" operation, as I recall, but otherwise should work the same as your local sprintf.

        -- Randal L. Schwartz, Perl hacker

        The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://804207]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2014-12-28 17:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (182 votes), past polls