[Shootout-list] floating point rounding
Joel Hoffman
hoffmanj@pacifier.com
Thu, 31 Mar 2005 09:10:48 -0800
Daniel South wrote:
>Haven't used Lisp for more years than I want to remember :-)
>Looks like it uses round down.
>
>Isaac, as a way to resolve this, you could extend the benchmark
>precision out to 3 decimal places. None of the tests have a 5 in the 4th
>decimal place followed by all 0s. This will give a uniform result no
>matter which of the three rounding methods the language uses (all three
>methods are valid).
>
>Daniel South
>
>
Well, that's not really a general solution but it would solve this
specific problem. Simply printing the count as an integer would resolve
it entirely.
This may be all due to a simple floating point rounding error at 0.005
in some of the languages - I believe Perl, Python and Ruby round to 0.49
at 0.495 and to 0.24 at 0.245, because of the rounding error, but
otherwise up at half boundaries. Yes, this has bitten me in the ass
before...
When I was testing with the Java program, 0.5 was represented at full
precision with something like 0.5000000000002242 . Again that doesn't
make sense. I'm using the Blackdown VM, and I don't know what sort of
floating point system it uses, but unless I'm very confused, inverse
powers of two are represented precisely with IEEE fp numbers.
Try this with gcc to see what I mean. It is definitely NOT rounding
toward even numbers, else 0.495 and 0.505 would both round to 0.5. But
0.495 is only approximately represented as 0.494999999999....
#include <stdio.h>
int main(void) {
printf("%0.02f\n",0.495); /* 0.49 */
printf("%0.02f\n",0.005); /* 0.01 */
printf("%0.02f\n",0.505); /* 0.51 */
printf("%0.02f\n",0.496); /* 0.50 */
printf("%0.02f\n",0.494); /* 0.49 */
}
Joel