[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