Anyone willing to help a beginner?

Quote:

>> I'm trying to learn Forth83 with Leo Brodie's "Starting Forth".

>> I've been doing all the problems, and have made my way half-way through

>> the book. Now, upon reaching the chapter on double-length numbers, I've

>> discovered that the version of Forth83 that I have is missing the word

>> M*/. Not only that, but I've spent hours downloading other versions of

>> Forth, all missing that word. It is supposed to multiply a 32-bit

>> number by a 16-bit number and divide the triple-length result by a

>> 16-bit number, returning a 32-bit result. I'm now going to try to write

>> my own definition for it, but I'm afraid that I don't have a great

>> enough understanding of the material to be successful. I was going to

>> find another version of Forth including the word, and steal the

>> definition from that version's source code. Now, I'd really appreciate

>> it if someone could help me out. I either need a version with the word

>> or a working definition of the word or even a tip on how to write such a

>> definition.

>> Thanks

>> Geniece McCollum

>Here is an extract of the code extracted from Win32Forth, to do what

>you want.

>The only problem you will probably still have, is possibly with

>having a definition of UM*, UM/MOD and INVERT.

Here are high-level definitions for UM* and UM/MOD. These are taken from

MAF (Minimal ANS Forth), which is written for study not for speed, so words

which are code definitions in most Forths are colon definitions in MAF.

([FW] indicates words taken from the FIG UK magazine Forthwrite.)

\ System Characteristics ------------

tI : FindBits/Cell \ Computes 2 characteristics of the

( -- Bits/Cell HighBit ) \ implementation.

tI 1 1 BEGIN \ Find the HighBit by shifting the

tI DUP 2* \ least significant bit upwards until

tI WHILE \ just before it pops off the top of

tI 2* \ the word and leaves 0.

tI SWAP 1+ SWAP

tI REPEAT ;

tI FindBits/Cell \ Compute the results and record them.

tI CONSTANT HighBit

tI : SignsDiffer? \ Support for <+Loop> < U< and M*.

\ ( n1 n2 -- Truth ) \ HighBit is set for -ve integers.

tI XOR \ Find the bits which differ.

tI HighBit AND 0<> \ Is one of them the HighBit?

tI ;

tI : US>D \ Convert the number u to the

\ ( u -- ud ) \ number d with the same numerical

tI 0 \ value.

tI ;

tI : UD>S \ Convert the double number ud to the

\ ( ud -- u ) \ single number u with the same

tI DROP \ numerical value.

tI ; \ To report 'result out of range',

\ substitute 0<> IF -11 THROW THEN

\ for DROP.

tI : D+ \ [FW] From the Double-Number word set.

\ ( d1|ud1 d2|ud2 -- d3|ud3 ) \ Used by UM* and UM/MOD.

tI >R

tI ROT OVER + \ Add the less significant cells.

tI DUP >R

tI U> IF \ If their sum is less than one of

tI 1+ \ them then the addition overflowed,

tI THEN \ so increment one of the more

tI R> \ significant cells.

tI SWAP R> + \ Add the more significant cells.

tI ;

tI : DU< \ [FW] From the Double Number Extension

\ ( ud1 ud2 -- Truth ) \ word set. Used by UM/MOD.

tI ROT 2DUP <> IF \ If the more significant cells <> ...

tI SWAP \ Exchange them ready for U<.

tI 2SWAP \ Prepare to drop the less sig. cells.

tI THEN

tI 2DROP \ Drop the unwanted cells

tI U< \ and compare the others.

tI ;

\ Multiply and Divide ----------------

\ Design Note: UM* achieves multiplication by repeated doubling and occasional

\ addition. u1 is doubled in a loop and at each doubling, if the matching

\ bit from u2 is set, then the current value of u1 is added into the result.

\ For example, to multiply 3 by 2 use:

\ 5 6 UM*

\ The stack values at points X and Y in the loop will be:

\ X: udProduct du1 b Y: udProduct du1

\ 0 0 6 0 1 6 0 12 0

\ 6 0 12 0 0 6 0 24 0

\ 6 0 24 0 4 30 0 48 0

tI : UM* \ Unsigned multiply achieved by

\ ( u1 u2 -- udProduct ) \ repeated doubling and occasional

\ \ addition.

tI >R \ Save u2.

tI 1 >R \ Save a bit mask, m, initially 1.

tI 0 US>D \ udProduct, initially 0.

tI ROT US>D \ Convert u1 to du1 to give

tI \ -- udProduct du1 ).

tI BEGIN \ For every bit in u2 ...

tI SWAP 2* >R \ Double m and save it.

tI \ X \ -- udProduct du1 b ) ( R:-- u2 m*2 )

tI IF \ If b is set ...

tI 2SWAP 2OVER D+ 2SWAP \ Add du1 to udProduct.

tI THEN

tI 2DUP D+ \ Y \ Double du1.

tI OR UNTIL

tI 2DROP R> R> 2DROP

tI ;

tI : M* \ Signed multiply.

\ ( n1 n2 -- d )

tI 2DUP SignsDiffer? >R \ Save the flag.

tI ABS SWAP ABS \ Convert to unsigned

tI UM* \ and multiply.

tI R> IF \ Apply sign if needed.

tI DNEGATE

tI THEN

tI ;

\ Design Note: (UM/Mod) achieves division by repeated doubling and occasional

\ addition. Recursion is used to provide two matching loops used as follows.

\ The divisor ud2 is saved on the return stack and doubled in the first loop.

\ The remainder ud3 is given the initial value ud1 and the quotient u4 is

\ initially 0.

\ A second loop is now executed the same number of times as the first,

\ doubling u4 with each cycle and comparing ud3 with the appropriate ud2i

\ taken from the return stack.

\ For example, to divide 7 by 2 use:

\ 7 0 2 0 (UM/Mod)

\ The stack values at points X and Y in the second loop will be:

\ X: u4 ud3 ud2 Y: ud3 u4

\ 0 7 0 8 0 TRUE => no action => 7 0 0

\ 0 7 0 4 0 FALSE => action => 3 0 1

\ 2 3 0 2 0 FALSE => action => 1 0 3

tI : (UM/Mod) \ Support for UM/MOD, factored out

\ ( ud1 ud2 -- ud3 u4 ) \ to allow recursion. Gives quotient

\ u4 and remainder ud3.

tI 2DUP >R >R \ Save value of ud2i in this cycle.

tI 2OVER 2OVER DU< \ If ud2i is now > ud1 or

tI OVER HighBit AND \ ud2i cannot double again ...

tI OR IF \ cease recursion.

tI 2DROP 0 \ Set ud3=ud1, u4=0 and let recursion

tI ELSE \ unwind.

tI 2DUP D+ \ Double ud2i

tI RECURSE \ and repeat

tI 2* \ As recursion unwinds,

tI THEN \ double u4 (initially u4=0).

tI ROT ROT \ Bury u4 under ud3.

tI R> R> \ Fetch ud2i for this cycle.

tI 2OVER 2OVER DU< \ X

tI IF \ If ud3 < ud2i ...

tI 2DROP ROT \ Tidy up.

tI ELSE \ Else do the work ...

tI DNEGATE D+ \ ud3 = ud3 - ud2i

tI ROT 1+ \ Increment u4.

tI THEN \ Y

tI ;

tI : UM/MOD \ ( ud1 u2 -- u3 u4 ) \ Divide ud1 by u2, giving the

tI ?DUP IF \ quotient u4 and the remainder u3.

tI US>D (UM/Mod) >R UD>S R>

tI ELSE \ If ud1=0 ...

tI 2DROP 0 0 \ this code just returns 0 0.

\ \ To report 'divide by 0', substitute

tI THEN \ -10 THROW.

tI ;

tI : FM/MOD \ [FW] divide d1 by n1 giving the

\ ( d1 n1 -- n2 n3 ) \ floored quotient n3 and the

\ remainder n2.

tI DUP >R ABS \ Save n1 and make it +ve.

tI ROT ROT DUP >R DABS \ Save d1 and make it +ve.

tI ROT UM/MOD \ -- n2 n3 )

tI OVER IF \ if the remainder n2 <> 0 ...

tI 1+ \ increment the quotient n3.

tI THEN

tI NEGATE \ n3 = -n3

tI THEN

tI R> 0< IF \ If n1 -ve ...

tI SWAP NEGATE SWAP

...

**read more »**