[erlang-questions] Any way to correct the round off errors?

Richard O'Keefe ok@REDACTED
Mon Sep 21 03:31:13 CEST 2009


On Sep 20, 2009, at 11:35 PM, G.S. wrote:

> Hello everyone,
>
> When subtracting in Erlang: 0.92915-0.92945 we should get -0.0003  
> but Erlang
> gives: -2.9999999999996696e-4   (when doing 92915-92945 Erlang gives  
> -30 so
> that's ok).
>
> Anyway to make make it give -0.0003 ?, and in general make it give  
> more
> accurate answers?


Erlang *DID* give you the most accurate answer possible.
Here is a little C program.

m% cat zoo.c
#include <stdio.h>

int main(void) {
     double const x = 0.92915;
     double const y = 0.92945;

     printf("0.92915           =  %.20f\n", x);
     printf("          0.92945 =  %.20f\n", y);
     printf("0.92915 - 0.92945 = %.20f\n", x - y);
     return 0;
}

m% cc zoo.c
m% a.out
0.92915           =  0.92915000000000003144
           0.92945 =  0.92944999999999999840
0.92915 - 0.92945 = -0.00029999999999996696

The problem is that the numbers 0.92915 an 0.92945
CANNOT BE REPRESENTED EXACTLY IN BINARY FLOATING-POINT.
There's a new standard for decimal floating-point,
which I believe is supported in shipping versions of
the z/Series and POWER machines, and it will take a lot
of the nasty surprise out of things like this.

The answer you got involved four steps where round-off
error can occur:
	decimal -> binary
	decimal -> binary again
	subtraction
	binary -> decimal
Giving any answer than what Erlang gave would be giving
WRONG answers.

If you want to *print* the result to a lower precision,
so that the effects of round-off error are (sometimes)
(partially) hidden (if you are lucky), that's easy.
The interactive top level will already print this number
as -3.00000e-4.  You can use vaguely C-like formats such
as io:fwrite("~.6g", [-0.00029999999999996696]).

Note that this doesn't change what the answer *is* (it's
already as good as you have any right to expect), it
just changes *how it is displayed*.




More information about the erlang-questions mailing list