Can someone explain this behavior? I am well aware of machine-level representation of floating point numbers. This seems to be related to printf and its formats. Both numbers are represented exactly by floating-point notation (check: multiplying by 64 gives an integer).
#include <stdio.h>
#include <iostream>
using namespace std;
int main() {
double x1=108.765625;
printf("%34.30f\n", x1);
printf("%9.5f\n", x1);
printf("%34.30f\n", x1*64);
double x2=108.046875;
printf("%34.30lf\n", x2);
printf("%9.5f\n", x2);
printf("%34.30f\n", x2*64);
}
Output:
> 108.765625000000000000000000000000
> 108.76562
> 6961.000000000000000000000000000000
> 108.046875000000000000000000000000
> 108.04688
> 6915.000000000000000000000000000000
Note, the first number gets rounded down, and the second one gets rounded up.
Note that the value returned by sprintf is rounded, due to the specified print format.
You have to use external commands because there is no built-in rounding feature in printf(1) , and the POSIX shell doesn't have built-in floating-point arithmetic. To round to the nearest decimal digit, you add 0.5 and truncate. To round to the nearest tenth, you divide the "nudge factor" by 10, and so forth.
It's "round half to even" or "Banker's rounding". The last digit of the rounded representation is chosen to be even if the number is exactly half way between the two.
http://linuxgazette.net/144/misc/lg/a_question_of_rounding_in_issue_143.html:
"For the GNU C library, the rounding rule used by printf() is "bankers rounding" or "round to even". This is more correct than some other C libraries, as the C99 specification says that conversion to decimal should use the currently selected IEEE rounding mode (default bankers rounding)."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With