[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