Sujet : Re: Back & Forth - Co-routines
De : melahi_ahmed (at) *nospam* yahoo.fr (ahmed)
Groupes : comp.lang.forthDate : 01. Feb 2025, 09:22:01
Autres entêtes
Organisation : novaBBS
Message-ID : <6efc4fec918d6d2bc29250159bafb5de@www.novabbs.com>
References : 1 2 3 4
User-Agent : Rocksolid Light
On Sat, 1 Feb 2025 7:26:11 +0000, Anton Ertl wrote:
Paul Rubin <no.email@nospam.invalid> writes:
This seems more in the locals spirit:
>
: blend { a x b -- n } 100 b x - b a - */ ;
: tri_mf3.1 { x a b c -- mf }
a x <= x b < AND IF b x a blend EXIT THEN
b x <= x c < AND IF b x c blend EXIT THEN
0 ;
>
Forth has a word WITHIN that should come in handy here:
>
: tri_mf3.1 { x a b c -- mf }
x a b within IF b x a blend EXIT THEN
x b c within IF b x c blend EXIT THEN
0 ;
Yes, it works fine. Thanks.
Another alternative, assuming a<=b<=c:
>
: tri_mf3.1 { x a b c -- mf }
case
x a < ?of 0 endof
x b < ?of b x a blend endof
x c < ?of b x c blend endof
0 0
endcase ;
It also works fine without problems.
>
The disadvantage in the latter case is that the above and below cases
are separate, needing another branch and possibly increasing the
number of mispredictions. This can be addressed with:
>
[undefined] select [if]
: select ( u1 u2 f -- u )
if swap then nip ;
[then]
>
: tri_mf3.1 { x a b c -- mf }
x a c within if
b x x b < a c select blend
else
0
then ;
This latter gives wrong results:
-100 -50 0 50 tri_mf3.1 . 0 ok \ this is true
-50 -50 0 50 tri_mf3.1 . -4900 ok \ false, must be 0
-10 -50 0 50 tri_mf3.1 . -900 ok \ false, must be 80
0 -50 0 50 tri_mf3.1 . \ here division by zero
*the terminal*:47:12: error: Division by zero
0 -50 0 50 >>>tri_mf3.1<<< .
I think it must be:
(the true/false flag must on tos for select as you defined it)
: tri_mf3.1 { x a b c -- mf }
x a c within if
b x a c x b < select blend
else
0
then ;
and this one works fine.
-100 -50 0 50 tri_mf3.1 . 0 ok
-50 -50 0 50 tri_mf3.1 . 0 ok
-10 -50 0 50 tri_mf3.1 . 80 ok
0 -50 0 50 tri_mf3.1 . 100 ok
10 -50 0 50 tri_mf3.1 . 80 ok
50 -50 0 50 tri_mf3.1 . 0 ok
100 -50 0 50 tri_mf3.1 . 0 ok
>
In Gforth (development) SELECT is a primitive which hopefully does not
branch; in that case you have only one branch here.
>
- anton
Ahmed
--