5 = 5, and 7 is odd, so 2.675 rounds to 2.67
5 = 5, and 8 is even, so 2.685 rounds to 2.69
Well, in theory. But floating point numbers can't actually represent 2.675 nor 2.685, so the rounding for these cases is actually determined by what numbers can be represented in floating point and are closest to those numbers:
DB> x sprintf "%.20f %.2f", (2.675)x2 0 '2.67499999999999980000 2.67' DB> x sprintf "%.20f %.2f", (2.685)x2 0 '2.68500000000000010000 2.69' DB>
which happens to agree with your assertion, but for the wrong reason. Change 6 to 4 to see a case that disagrees (at least on my system):
DB> x sprintf "%.20f %.2f", (2.475)x2 0 '2.47500000000000010000 2.48' DB> x sprintf "%.20f %.2f", (2.485)x2 0 '2.48499999999999990000 2.48' DB>
Finally, just to show how close floating point can get on the other side of one of these examples:
DB> x pack "d", 2.675 0 "ffffff\cE\@" DB> x unpack "d", "gfffff\cE\@" 0 2.675 DB> x sprintf "%.20f %.2f", (2.675)x2 0 '2.67499999999999980000 2.67' DB> x sprintf "%.20f %.2f", (unpack "d", "gfffff\cE\@")x2 0 '2.67500000000000030000 2.68'
And, this may give you some idea how many different values you might compute that Perl would report as just "2.675" but that can round differently:
DB> x unpack "d", "qfffff\cE\@" 0 2.675 DB> x unpack "d", "rfffff\cE\@" 0 2.67500000000001
- tye
In reply to Re^2: sprintf and decimals (theory)
by tye
in thread sprintf and decimals
by nosbod
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |