AltME: REBOL3

Messages

Ladislav
To answer Peter's question: Currently, EQUAL? is not only nontransitive for decimals, it is also "approximate" in that different numbers (differing by 10 ULP or less) are considered equal. For example, 0.1 + 0.1 + 0.1 (to binary! 0.1 + 0.1 + 0.1; == #{3FD3333333333334}) differs from 0.3 (to binary! 0.3 ; == #{3FD3333333333333}) by exactly 1 ULP (unit in in the last place), as can be seen from the binary representation.
EQUAL? 0.1 + 0.1 + 0.1 0.3 yields TRUE
Ladislav
..., while the number representing 0.1 + 0.1 + 0.1 is exactly by 1 ULP greater than the number representing 0.3, and greater-or-equal? 0.1 + 0.1 + 0.1 yields TRUE, while lesser-or-equal? 0.1 + 0.1 + 0.1 0.3 yields FALSE
If we defined EQUAL? to be equivalent to the conjunction of LESSER-OR-EQUAL? and GREATER-OR-EQUAL? (which we should to be consistent), while retatining both the definition of LESSER-OR-EQUAL? and GREATER-OR-EQUAL? we would obtain that 0.1 + 0.1 + 0.1 has to be unequal to 0.3 (actually greater than 0.3).
DideC - no, I used word comparison only as an illustration why nontransitive relations cannot be used as orders for sorting. Otherwise, word! is a separate datatype, and the issue with word ordering should be resolved separately.
Ladislav
Using present definitions of LESSER-OR-EQUAL? and GREATER-OR-EQUAL? for decimals, and defining EQUAL? as their conjuction, we would obtain a transitive equality, but it would not be approximate.
It turns out that we *can* define a transitive approximate equality, but we cannot do it so that it will be always "tolerant".
The way how to do it is to define some subset of decimals and some rounding, and say that two decimals are approximately equal if they round to the same value. This is guaranteed to be both approximate as well as transitive.
Ladislav
The only problem is that it is not always "tolerant" in the sense that can be illustrated by an example: let's use rounding to the nearest integer, then the numbers greater than 0.0 and smaller than 0.5 round to 0.0, while numbers greater or equal to 0.5 and smaller than 1.5 round to 1.0. This is a transitive relation that is quite tolerant, but it is not always tolerant, since the numbers 0.49999999999999994 and 0.5 round to 0.0 and 1.0 respectively, and are not nearly equal, although they differ only by one ULP.
Ladislav
Our consolation is that this happens only exceptionally, on the "boundary" between successive rounding areas.
I know that this is not trivial stuff, so please ask if anything is unclear to you.
Ladislav
To compare it to other languages, to not run into difficulties, they use only zero-tolerance (strict) comparison, which is guaranteed to be transitive, and inform the user to use a more tolerant comparison where appropriate, leaving her on her own to do it.
PeterWood
Thanks Ladislav. I found the explanation very clear. Given that one of the premises of Rebol, if I remember correctly, is pragmatism, I can understand why Carl would adopt the current behavior. It gives the "expected" answer in most people's eyes (but not those of an expert).
Is there not an argument to retain the current behaviour for equal? but change strict-equal? to be transitive?

Ladislav
Hi, I added an experimental example of a transitive approximate equality. Testing and playing with it welcome.
Ladislav
"Is there not an argument to retain the current behaviour for equal? but change strict-equal? to be transitive?" - hmm, I guess that I know what you wanted to ask. Given a transitive approximate-equal? (AE?) function, we can easily define a transitive approximate-lesser-or-equal? (ALE?) function. The definition would be as follows: ALE?: func [x [decimal!] y [decimal!]] [((lesser? x y) or (ae? x y))]. We could also define approximate-lesser? (AL?) function: AL?: func [x [decimal!] y [decimal!]] [(lesser? x y) and not (ae? x y)], etc.
Does that answer your question, Peter?

PeterWood
Perhaps Ladislav. What I am asking is whether it would be good to retain the current behaviour for equal?. I'm sure that Carl implemented it that way with good reason. I realise that this may still be the result with the transitive approximate-equal? (but Im not sure).
I feel that these two examples of the current equal? behaviour should be retained (if possible):
>> equal? 0.49999999999999994 0.5
== true
>> equal? 0.1 + 0.1 + 0.1 0.3
== true
but that this behaviour should be changed:
>> strict-equal? 0.49999999999999994 0.5
== true -->> false
>> strict-equal? 0.1 + 0.1 + 0.1 0.3
== true -->> false
>> strict-equal? 0.1 + 0.1 + 0.1 0.3
== true
DideC
It's what I though too.
Same behaviour for '= and '== of course.
But it does not answer to the 'lesser-or-equal? and 'greater-or-equal? transitivity question.
PeterWood
I left an extra line in my posting :-(
What I am suggesting that it would be good for equal? to use Ladislav's transitive approximate-equal? but strict-equal? should check that the values are actually equal. So that the future behaviour would be
>> equal? 0.1 + 0.1 + 0.1 0.3
== true
>> strict-equal? 0.1 + 0.1 + 0.1 0.3
== false

Last message posted 161 weeks ago.