I'm no expert, but will add some comments.
(1) What is displayed does not necessarily reflect the value. Apparently
REBOL
doesn't like to print long strings of leading zeros nor 99999's.
(2) Obviously, there are a limited number of bits available, and some
decimal
numbers (e.g. 0.2) may not be expressible in a finite number of binary
digits.
(3) Your examples, which mix integers and decimal types, depend a lot on
how
the REBOL designers interpret mixed type expressions. However, that doesn't
seem to have
caused you problems.
>> 1. - 2.e-15
== 0.999999999999998
>> 1. - 2.e-16
== 1
>>
This illustrates (1) above.
Here are some more examples:
>> index: 1. - 2.e-32
== 1
>> index - 1.
== 0 ; I think this illustrates REBOL lacks enough bits to express this
number, so REBOL does round it
to 1. (1. - 2.e-32) would take over 100 binary digits, probably in excess
of REBOL's capability (which I guess is 64 bits) 1. - 2.e-16 takes about 53
bits, so 64 bits can handle it with about 10 binary bits of precision.
>> index: 1. - 2.e-16
== 1
>> index - 1.
== -2.22044604925031E-16
>>
REBOL does not "round" when converting decimals to integers - it merely
discards the fractional part.
This explains your pick examples.
I dimly remember some previous discussions here about the various REBOL
compare words, and I believe you're correct that they don't work per the
documentation nor always completely logically.
For your work you might consider creating an object with a member for the
integer part and another decimal type member for the fractional part.
Please take the above with the customary grain of salt - as, again, I'm no
expert!
Russell, [EMAIL PROTECTED]
----- Original Message -----
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Friday, September 24, 1999 11:30 PM
Subject: [REBOL] problem with decimal values
>
> Hi,
>
> I've had a lot of problems with decimal values very near integer values
> not being what they look like. The latest trouble I've had occurred when
> writing a simple histogram function. I calculated the index into a block
> and wound up with a value that was about 1 - 2e-16. Since Rebol does
> imprecise comparisons, such a value looks like 1 until you try to use it:
>
> >> index: 1 - 2e-16
> == 1
> >> index = 1
> == true
> >> pick [1 2 3 4 5] index
> == none
> >> to-integer index
> == 0
>
> Also:
>
> >> index2: 2 - 2e-16
> == 2
> >> pick [1 2 3 4 5] index2
> == 1
>
> I think Rebol is trying help us by "shielding" us from floating-point
> round-off errors, but this means that when the problems pop up farther
down
> the road, they can be really hard to pin down. Rebol does have
STRICT-EQUAL?
> and == , but those just detect the difference between integer and decimal
> datatypes, and can return false when the values really are equal:
>
> >> index == 1
> == false ; cool, but ...
> >> 1.0 == 1
> == false
>
> I've been doing some translations from Numerical Recipes in C into Rebol,
and
> found that I've had to roll all my own comparison functions. For a lot of
> calculations, results like
>
> >> 1e-16 = 1e-32
> == true
> >> 1e-16 == 1e-32
> == true
>
> are bizarre! I'm sending this to feedback as well, but I'd be very
interested
> to hear if anyone on the list has opinions on this topic.
>
> Thanks,
> Eric
>
> PS - Has anyone ever found a use for =? SAME? or STRICT-NOT-EQUAL? ?
>
> In case anyone's interested, here's how I put together the comparison
> functions:
>
> cmp: func[
> {comparison: returns 1 if v1 > v2, 0 if v1 = v2, -1 if v1 < v2}
> v1 v2 /local diff
> ][
> either any-string? v1 [
> v1: to-binary v1 ; allows case-sensitive string comparison
> v2: to-binary v2
> either v1 = v2 [0][either v1 > v2 [1][-1]]
> ][
> either number? v1 [
> either zero? diff: v1 - v2 [0][
> while [0 = diff][diff: diff * 256] ; magnify the
difference
> either diff > 0 [1][-1]
> ]
> ][either v1 > v2 [1][either v2 = v1 [0][-1]]] ; default
> ]
> ]
>
> gt: func [{returns TRUE if the first one is greater} v1 v2][
> either 1 = cmp v1 v2 [true][false]
> ] ; and so on ...
>
> >> gt 1e-16 1e-32
> == true
>
>