: AVG DEPTH 0 SWAP DUP >R 0 DO SWAP + LOOP R> / . ;
r \ Move the number of floating point values to the return stack1 \ Initialize loop counter to 1
\ Move the number of floating point values to the stackf/ \ Divide sum by number of floating point values to get average
f \ Convert the number of floating point values to a float
On 11/07/2024 8:08 am, Buzz McCool wrote:
On 6/7/2024 1:32 PM, LIT wrote:
: AVG DEPTH 0 SWAP DUP >R 0 DO SWAP + LOOP R> / . ;
I coincidentally was doing averaging for the floating point stack when I
ran across this posting. Other than adding stack comments, how can I
improve this word?
Uses less words than BEGIN REPEAT but compiles to more code under VFX
...
: FAVG ( rn ... r -- avg )
fdepth dup >r 1- 0 ?do f+ loop r> s>f f/ ;
Non standard
: FSAVG fdepth dup 1- FOR f+ NEXT s>f f/ ;
How can I get FOR and NEXT with MinForth? I have MF384.
Simpler to count down. I find it easier writing for a common-stack model.
: FloatStackAvg ( rn ... r -- avg )
fdepth dup >r ( count)
begin 1- dup while ( not done)
>r f+ ( add two floats) r>
repeat drop
r> s>f f/ ( sum/count)
;
>r f+ ( add two floats) r>
; okf f/
On 6/7/2024 1:32 PM, LIT wrote:
: AVG DEPTH 0 SWAP DUP >R 0 DO SWAP + LOOP R> / . ;
I coincidentally was doing averaging for the floating point stack when I
ran across this posting. Other than adding stack comments, how can I
improve this word?
Buzz McCool <buzz_mccool@yahoo.com> writes:
On 6/7/2024 1:32 PM, LIT wrote:
: AVG DEPTH 0 SWAP DUP >R 0 DO SWAP + LOOP R> / . ;
I coincidentally was doing averaging for the floating point stack when I >>ran across this posting. Other than adding stack comments, how can I >>improve this word?
Eliminate DEPTH, e.g., by replacing it with a count of the elements
you want to average over, or better, write a word that takes only a >descriptor of, e.g., an array in memory, and averages over the array.
Why should DEPTH not be used in this way? Because it means that AVG_ >consumes the whole stack and is useless in a word that keeps some
temporary data deeper in the stack when it calls another word, an
idiomatic way of using Forth.
- anton
On 12/07/2024 2:35 am, Buzz McCool wrote:
On 7/10/2024 8:31 PM, dxf wrote:
Simpler to count down. I find it easier writing for a common-stack model. >>>
: FloatStackAvg ( rn ... r -- avg )
fdepth dup >r ( count)
begin 1- dup while ( not done)
>r f+ ( add two floats) r>
repeat drop
r> s>f f/ ( sum/count)
;
Thanks for sharing.
What is the purpose of putting something on and then off the return stack on this line?
>r f+ ( add two floats) r>
Your example word seemed to work fine without it.
Traditionally floats existed on the data stack along with integers, doubles etc.
This required being sensitive to what was on top of the stack. As time passed some
argued floats should have their own stack. That's now progressed to Forth-200x
outlawing floats on the data stack. Implementing a separate float stack is usually
no issue for 16-bit processors and above but for 8-bit cpu's it's prohibitive.
My observation is the same people that push for locals also push for floats on a
separate stack using essentially the same argument.
On 7/10/2024 8:31 PM, dxf wrote:
Simpler to count down. I find it easier writing for a common-stack
model.
: FloatStackAvg ( rn ... r -- avg )
fdepth dup >r ( count)
begin 1- dup while ( not done)
>r f+ ( add two floats) r>
repeat drop
r> s>f f/ ( sum/count)
;
f f/ ; ( sum/count)
IMO it is not more than a quick hack to digest the full fp stack,I understand where you (and Anton) are coming from. I was thinking that FloatStackAvg was a one-and-done word, but someone might want to use it
whatever it may contain or not at the given moment. ...
While c.l.f. challenges are often couched in terms of items on a stack,
one is more likely to be dealing with data in memory and a count.
Shifting the operation to the stack (assuming that's even viable) strikes
me as unnecessary.
Thanks for the explanation.
How can I get FOR and NEXT with MinForth? I have MF384.
Ahmed
On 2024-07-11, ahmed <melahi_ahmed@yahoo.fr> wrote:
Thanks for the explanation.
How can I get FOR and NEXT with MinForth? I have MF384.
Ahmed
In pforth (pfe), that's why I use to test code made for eforth:
: >MARK ( --A ) HERE 0 , ;
: AHEAD ( --A ) COMPILE branch >MARK ; IMMEDIATE
: AFT ( a --a A ) DROP [COMPILE] AHEAD [COMPILE] BEGIN SWAP ; IMMEDIATE
: FOR ( RUNTIME: N -- )
COMPILE ABS \ NO NEGATIVES
COMPILE LIT 0 , COMPILE SWAP
[COMPILE] ?DO ; IMMEDIATE
: NEXT
COMPILE LIT -1 ,
[COMPILE] +LOOP ; IMMEDIATE
On 14-05-2025 09:07, ahmed wrote:
On Wed, 14 May 2025 5:51:35 +0000, anthk wrote:
On 2024-07-11, ahmed <melahi_ahmed@yahoo.fr> wrote:
Thanks for the explanation.
How can I get FOR and NEXT with MinForth? I have MF384.
Ahmed
In pforth (pfe), that's why I use to test code made for eforth:
: >MARK ( --A ) HERE 0 , ;
: AHEAD ( --A ) COMPILE branch >MARK ; IMMEDIATE
: AFT ( a --a A ) DROP [COMPILE] AHEAD [COMPILE] BEGIN SWAP ; IMMEDIATE
: FOR ( RUNTIME: N -- )
COMPILE ABS \ NO NEGATIVES
COMPILE LIT 0 , COMPILE SWAP
[COMPILE] ?DO ; IMMEDIATE
: NEXT
COMPILE LIT -1 ,
[COMPILE] +LOOP ; IMMEDIATE
Thanks.
I've already defined for and next in MinForth like this:
: (0) 0 ;
: (-1) -1 ;
: for_ postpone (0) postpone swap postpone ?do ; immediate
: _next postpone (-1) postpone +loop ; immediate
and here is an example of use:
: go_ 10 for_ i . _next ;
go_ 10 9 8 7 6 5 4 3 2 1 0 ok
Well, it isn't standardized - so you can make it anything you want to. I
got two variants, the one I think it should be, and the one from eForth:
:macro for >r begin r@ 0> while ;
:macro next r> 1- >r repeat rdrop ;
eForth:
:macro for >r begin ;
:macro next r@ 0> while r> 1- >r repeat rdrop ;
They *SEEM* almost identical, but they aren't. The eForth one performs
"the action" before the condition is tested, mine *AFTER* the condition
is tested.
Now - what do I expect when I issue a "10"? I expect a thing to be
performed ten times. No more, no less. And that's what mine gets. The
eForth one does not ten things, but eleven (including the zero). Also
note my version fixes another DO..LOOP problem - it bombs out when the
count is zero or less.
Finally, we all agree DO..LOOP is deeply flawed (it is) but we still
prefer to use it - preferably with loops with negative subscripts, or garnishing it with horrors like UNLOOP and LEAVE (Hello! - it's a
*counted* loop. It should do as many times as I asked it to do initially
- not halfway change my mind saying "Oops - now I want you to quit
anyway").
In a 1000 line Forth program I use DO..LOOP 11 times - none with LEAVE
or UNLOOP. In another 500 line program, not at all. So if I had to
encode FOR..NEXT I wouldn't choose DO..LOOP - for obvious reasons.
Hans Bezemer
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 504 |
Nodes: | 16 (2 / 14) |
Uptime: | 244:53:35 |
Calls: | 9,891 |
Files: | 13,794 |
Messages: | 6,294,410 |