# decimal woes

### [1/10] from: lmecir::mbox::vol::cz at: 18-Jul-2003 17:23

Hi Max,
you can use e.g.:
do http://www.fm.vslib.cz/~ladislav/rebol/rounding.r
time: 0
loop 50 [
time: round/to time + 0.02 0.01
probe time
]
-L
----- Original Message -----
Hi all,
I am having fun converting SEISMIC data (sampled at 5 thousands of a second
:-) within a 30MB file.
I must dump all of this in a 3d animation package (maya) and its working...
except for one point..
decimal datatype is a little unstable, and maybe someone can tell me why
this happens:
if you do:
time: 0
loop 50 [
time: time + 0.02
probe time
]
ask ""
at the end you will have
0.92
0.940000000000001
0.960000000000001
0.980000000000001
but if you then do 0.92 + 0.02
you get 0.94
the floating point error gets worse and worse (and eventually diminishes a
little!!!)
there are only two signifiant digits in all calculus, I am wondering if it
could be possible for the floating point algorythms to be a little more
stable...
I had to an ugly integer calculation workaround divided by 100 to get the
clean decimals...
-max

### [2/10] from: maximo:meteorstudios at: 18-Jul-2003 11:01

Hi all,
I am having fun converting SEISMIC data (sampled at 5 thousands of a second :-) within
a 30MB file.
I must dump all of this in a 3d animation package (maya) and its working... except for
one point..
decimal datatype is a little unstable, and maybe someone can tell me why this happens:
if you do:
time: 0
loop 50 [
time: time + 0.02
probe time
]
ask ""
at the end you will have
0.92
0.940000000000001
0.960000000000001
0.980000000000001
but if you then do 0.92 + 0.02
you get 0.94
the floating point error gets worse and worse (and eventually diminishes a little!!!)
there are only two signifiant digits in all calculus, I am wondering if it could be possible
for the floating point algorythms to be a little more stable...
I had to an ugly integer calculation workaround divided by 100 to get the clean decimals...
-max

### [3/10] from: ptretter:charter at: 18-Jul-2003 11:30

That must be a bug from what I can gather. You might want to submit that to
feedback via www.rebol.com/feedback.html
Paul Tretter
----- Original Message -----
From: "Maxim Olivier-Adlhoch" <

**[maximo--meteorstudios--com]**> To: "Rebol-List (E-mail)" <**[rebol-list--rebol--com]**> Sent: Friday, July 18, 2003 10:01 AM Subject: [REBOL] decimal woes Hi all, I am having fun converting SEISMIC data (sampled at 5 thousands of a second :-) within a 30MB file. I must dump all of this in a 3d animation package (maya) and its working... except for one point.. decimal datatype is a little unstable, and maybe someone can tell me why this happens: if you do: time: 0 loop 50 [ time: time + 0.02 probe time ] ask "" at the end you will have 0.92 0.940000000000001 0.960000000000001 0.980000000000001 but if you then do 0.92 + 0.02 you get 0.94 the floating point error gets worse and worse (and eventually diminishes a little!!!) there are only two signifiant digits in all calculus, I am wondering if it could be possible for the floating point algorythms to be a little more stable... I had to an ugly integer calculation workaround divided by 100 to get the clean decimals... -max### [4/10] from: maximo:meteorstudios at: 18-Jul-2003 12:30

great! thanks
-Max

### [5/10] from: roland:hadinger:arcor at: 18-Jul-2003 18:51

Hi Maxim,
decimal fractions like 0.02 are typically represented as binary
fractions at the hardware level, in this case:
0.02 base 10 0.0_00001010001111010111_ recurring base 2
Due to the limited precision a roundoff error is introduced at the
the 23rd, 53th or 80th bit of the mantissa (depending on the floating
point format), which tends to accumulate when you do lots of
additions and subtractions.
One option would be to use fixed point arithmetic done with
premultiplied numbers.
Another option would be to rewrite the code:
time: 0.0
time-start: 0.0
time-end: 1.0
repeat n 50 [
m: n / 50
time: time-start * (1 - m) + time-end * m
probe time
]
Depending on the number of iterations, this may (not necessarily!)
be more accurate.

### [6/10] from: maximo:meteorstudios at: 18-Jul-2003 13:28

reply in-line
PS: check out the e-mail replacement...
it sometimes work when sites ask for passwords... the sysadmin receives their own spam
;-)

> -----Original Message-----
> From: Roland Hadinger [

**[root--localhost--com]**]<<quoted lines omitted: 7>>

> point format), which tends to accumulate when you do lots of
> additions and subtractions.
hum, wish I had a major in maths ;-)
I understand that fp usually accumulates errors (in cgi its a big problem with 8-bit/channel
gfx). But, if the value is going to be off by a small amount, shouldn't it be visible
with a print. I mean, If, in the loop, the value to add to is printed as 0.92 I expect
it to behave similarly as if I do 0.92 + 0.02 in the console... no?
Do you think this means that print and probe do not contain all digits of the internal
hw decimal value? so that when it prints 0.92 it only looked at the 15 first digits
and there was still some data past that, which only spills off after repeated (and expected)
rounding errors?
if so, does anyone know how to build a print-xtended-decimal function?

> One option would be to use fixed point arithmetic done with
> premultiplied numbers.

That's exaclty what I did, and it works (but its a bit ugly when you have built-in fp).
Working in the 'assumed' resolution of thousanths of a secound and dividing by 1000 when
doing comparisons with the supplied data, does work.

> Another option would be to rewrite the code:
>
> time: 0.0
> time-start: 0.0
> time-end: 1.0
>
> repeat n 50 [ ...]

alas, in the real code I do not know the lenght of the series (searching through data)
and must exit at tail? of series, so I cant implement it that way.

### [7/10] from: roland:hadinger:arcor at: 18-Jul-2003 21:21

> Do you think this means that print and probe do not contain
> all digits of the internal hw decimal value? so that when it
> prints 0.92 it only looked at the 15 first digits and there
> was still some data past that, which only spills off after
> repeated (and expected) rounding errors?

Yes. 'print and 'probe do some rounding, but when the error
accumulates (accuracy decreases), it starts to get noticeable.

> if so, does anyone know how to build a print-xtended-decimal function?

No. How would a print-xtended-decimal function know the "right"
from the "wrong" bits that have accumulated at the end?
I think there are some solutions, but they are...
- tricky: store the accuracy (number of significant digits)
of each decimal value separately. For each calculation, take
into account the accuracies of the operands and estimate
accuracy of result. Round accordingly when printing the
output, so only significant digits are displayed.
- slow: use arbitrary precision math routines (under
construction...).
- expensive: use something like Maple, MuPAD, or Mathematica,
which have most of the above methods already built in.
- messy and painful: chop off 10 - (2 ** n) fingers and forget
the decimal system :P
--
Roland

### [8/10] from: tomc:darkwing:uoregon at: 18-Jul-2003 13:39

Carl (S.) had at one point suggested including a "binary coded decimal"
type! and necessary op!s that would atleast cover the case in point.
On Fri, 18 Jul 2003, Roland Hadinger wrote:

### [9/10] from: greggirwin:mindspring at: 18-Jul-2003 19:46

Hi Tom,
TC> Carl (S.) had at one point suggested including a "binary coded decimal"
TC> type! and necessary op!s that would atleast cover the case in point.
Which would be nice for money! values. money! values suffer some
glitches when printed or probed as well right now.
-- Gregg

### [10/10] from: g:santilli:tiscalinet:it at: 19-Jul-2003 15:32

Hi Maxim,
On Friday, July 18, 2003, 7:28:06 PM, you wrote:
MOA> Do you think this means that print and probe do not contain
MOA> all digits of the internal hw decimal value?
Of course they don't. The internal representation is binary, while
they print in decimal. There's no point in showing an amount that
is lower than the error caused by the internal representation.
However, since you use repeated additions, this error sums up and
becomes "visible", i.e. big enough that PRINT thinks it is worth
showing.
In your case, fixed point arithmetic is probably the best
solution. If you want to use floating point, you have to take the
error into account. Or, at least you have to avoid operations that
can make the error grow, as in:
i: 0
loop 50 [
probe time: 2 * i / 100
i: i + 1
]
Regards,
Gabriele.
--
Gabriele Santilli <

**[g--santilli--tiscalinet--it]**> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/Notes

- Quoted lines have been omitted from some messages.

View the message alone to see the lines that have been omitted