For the things we have to learn before we can do them, we learn
by doing them.

Aristotle

STRENGTH IN FORTH
part two

THE GREEK CONNECTION

Last time I left you on the stack, with nothing to do. But we did
some arithmetic,  remember ?  We solved 3 5 + .  This time we are
going to do some more of that.  (That's why I would have left you
on  the stack anyway !).  In FORTH arithmetic is a matter  of  to
stack or not to stack....and numbers of course.  It is  therefore
essential  to  study  thoroughly the stack's  magic  and  FORTH's
numbers.

NUMBER & BUMPER

Now for the numbers. If you aren't acquainted with the basic (sic
!)  ins  and  outs of binary and  hexadecimal  representation  of
numbers both inside and outside a computer,  I suggest you to buy
a  book on that stuff.  It would be tiresome to get  through  all
that  here  and now.  So I assume at least you  know  enough,  to
understand the following explication.
A  computer  does  it  in  binary;  all  ones  and  nulls.  Thus,
computer's  maths are in binary as well.  Numbers are  stored  in
binary.  To  store  numbers you need some place  to  store  them:
locations,    memorylocations.   A   computer   can   find   each
The  smallest piece of memory used to store numbers is  called  a
byte. (Of course you may write, if you think you know better; but
it will cost you a life-time working to pay the back-postage ).
A byte consists of 8 bits.  Each bit can have the value of either
1 or 0. If you should write down all possible combinations of 0's
and 1's that fit into a byte, you would have a collection of 256
numbers, ranging from 0 to 255 inclusive.

THE GREAT DECEPTION

Meanwhile,  did you notice that a bit can be 0 or 1, i.e positive
(= 1), or not-positive (= 0), but NOT NEGATIVE. Handling positive
numbers  may  well be a natural way-of-life for  a  computer.  To
handle negative numbers,  we need to mislead the computer. We can
deceive it by the two's- complement arithmetrick.  Now,  FORTH is
16-bit oriented.  In unsigned 16-bit arithmetic the lowest number
you might represent is zero. In binary: 0000000000000000. And the
highest appears in binary as 1111111111111111,  which is 65535 in
decimal. In this constellation there are 65536 numbers. Now watch
the  trick !!  Consider what happens,  if I add 1 to the  highest
number(65535).

1111111111111111
+ 0000000000000001
(1)0000000000000000

As  I have only 16 bits,  the 1 in the 17th place  is  lost.  The
remaining 16 bits are stored as the value zero.  IF WE ADD A 1 TO
A  NUMBER AND THE RESULT IS 0,  WE THEN CAN EASILY INTERPRET  THE
ORIGINAL NUMBER (I.E.  1111111111111111) AS THE VALUE -1.
In this
way the computer is mislead to think 16 positive bits is -1.  So,
if 16 bits are positive (= TRUE),  a number is interpreted as -1.
Now  it will be clear to you,  why in computerlogic TRUE  is  -1;
because all bits are TRUE ! Keep that in mind: 16-bit numbers can
be  thought  of  as either signed  or  unsigned  numbers.  Signed
numbers  range from -32768 up to 32767.  Unsigned  numbers  range
from 0 up to 65535. All numbers are integers.
To learn how to ride on horseback, you have to sit on...and ride.
To use FORTH, you need to know how it works, to know how it works
you need to use FORTH.  We are going to use FORTH,  to see if  we
Just enter:  -1 {DUP} {.} {U.}  -1 65535OK. Let's trace back and
see what happened.
1.  -1 TOS 2.  DUP (means duplicate value TOS) 3.  . (outputs the
number TOS) 4. U.  (outputs the number TOS).
The stack shows: -1
-1

Now {.} removes the value TOS and prints it as a signed number.
The stack shows: -1
{U.} removes the value TOS and prints it as a unsigned number.
That's where the U stands for: Unsigned.
For  further elucidations on this subject we need to examine  the
binary form of -1 and 65535.  We can (I can,  you can't)  achieve
our goal by making a new word by defining a colondefinition.  The
name 'colondefinition' is quite obvious. The first character is a
colon.  Here it is.  :  B.  BASE C@ 2 BASE C! SWAP U. BASE C! ; 
OK.
As  a colon is a FORTH-word,  seperate it by a space  from  other
words.  Semi-colon  always ends a  colondefinition.  Perhaps  you
didn't realize,  but all numbers till now were output in  decimal
base,  FORTH's  default base.  You can easily change  that  base,
simply by storing a new basevalue in the word {BASE}. In the word
{B.} that was done through the sequence ..2 BASE C!..
Do it now.  2 {BASE} C!  OK. Now FORTH is in binary base. Again,
changing to octal base. 1000 {BASE} C!  OK. Why on earth 1000 ?
Because  we were in binary and 1000 is eight in binary.  Back  to
decimal again.  Well said, but how to type ten in octal ? Believe
me, it is 12. So 12 {BASE} C!  OK. The rest of {B.} is set up to
return  to decimal from binary.  There is one word  of  interest:
{SWAP}. {SWAP} exchanges the two top stack values. Type 3 5  OK
The stack shows: 5
3
Type  {SWAP}  OK.  Type {.}  3OK.  It is not much like  {.}  to
print  out  the  second  top stack  item,  so  {SWAP}  must  have
exchanged  our  two  little numbers,  5  becoming  second  and  3
becoming TOS. Let's try {B.} (say bee-dot). (One rainy day I will
teach how to define a Dolly-Dot-word, you bet.)
Type -1 {DUP} {B.} {.}  1111111111111111 -1OK.  Type 65535 {DUP}
{B.} {U.}  1111111111111111 65535OK.
See,  in binary there isn't any difference between -1 and  65535.
It is {.} and {U.} that makes a different OUTPUT.
And my Greek connection Aristotle proved he was right in what  he
was saying about learning things by doing them.
With  {B.}  you  may examine in which  way  FORTH  stores  16-bit
numbers  internally.  With  {.} and {U.} you may have a  look  at
their  signed and unsigned visual shapes.  (If you own a  non-83-
standard FORTH,  it may be that the stackwidth is not 16-bit, but
32-bit. All what was said and all what is to be said about 16-bit
applies equally for the numbers and operators designed for a  32-
bit stack. We'll make further remarks on 32-bit stacks in part 3)

Most arithmetic in FORTH is very simple.  Because you always deal
with  integers  of  a  fixed  range.  FORTH  supplies  sufficient
operators  to do all sorts of maths.  Sometimes you will have  to
write an operator yourself. I will give examples in this course .
There  is  still  more to tell about numbers.  But  for  now  the
subject is closed.  We will examine the operators.  All operators
to be spoken of in the next few lines,  work on 16-bits  integers
only.  Sixteen-bit  numbers are referred to as  single-length  or
single-precision numbers.  I prefer single-length:  short s.l. So
we discuss s.l.-operators.

FAMILYPORTRAIT

We've met one member of the clan,  {+}.  You already know him, so
say  hello.  Let's  proceed with {-}  (say:  minus).  Minus  acts
similar  to  the tax-official,  it subtracts.  It takes  the  two
numbers TOS,  subtracts and places the result back TOS.  Type 345
344 {-} {.} 
1OK.  Mind,  the  number to be subtracted must be highest on  the
stack.
Next to Minus is {*} (say:  star).  Star's job is to multiply the
two numbers highest on the stack and place the product back.  Pay
special attention to Star,  because it is likely to produce large
numbers,  which may exceed the 16-bit range.  Type 37 3 {*} {.} 
111OK.
The  fourth clanmember is {/} (say:  slash).  Slash was  born  to
divide, so he does. Whithout compassion: nothing remains.
Enter e.g. 83 4 {/} {.}  20OK. The remainder (3) is lost.
Slash' twin brother is {MOD} (say: mod). Mod ignores the quotient
and saves the remainder only. So 83 4 {MOD} {.}  3OK.
The  combination of Slash and Mod gives you and a quotient and  a
remainder. It is written as {/MOD} and pronounced slashmod. Enter
83  4  {/MOD} {.} {.}  20 3OK .  The result is not 20.3  or  the
like, as {/MOD} puts the quotient and the remainder as two 16-bit
numbers on the stack.
Star and Slash both have a specialised nephew {2*} and {2/} (say:
twostar - twoslash).  These are very fast operators.  As dividing
and multiplying by two are most common in use, FORTH's demand for
speed  is due to their birth.  Mind the difference between 2  {*}
and {2*}, as in writing (space), as well as in speed.

STARSLASH, THE MENACE

Some  lines ago I warned you when you use {*},  to be careful  to
stay  within the sixteen-bit range.  Now here I present  you  the
menace  of the clan.  The next operator isn't quite loyal to  the
Sixteenbitclan. It has a miscellaneous character. You write it as
{*/} and pronounce it as starslash.  This is how it  acts.  Enter
please  113 768 {*} 8 {/} {.}  and that's not the right  answer.
Now enter 113 768 8 {*/} {.}  10973OK.  And that's  right.  What
happened ?  In the first example the result of 113 768 {*} didn't
fit into 16 bits (113 x 768 = 87784).  In the second example  the
result of the multiplication-part of the operator {*/} is as long
as  32 bits !  This intermediate result is then divided by 8  and
the final result is put TOS as a s.l.-number.  (In 32 bits signed
numbers can range from -2147483648 to +2147483647 inclusive.)
The input on the stack for use by {*/} is always the two  numbers
to be multiplied first, followed by the divider.
Starslash  does  not supply a remainder,  as  does  {*/MOD}.  The
latter gives you everything:  speed, 32-bits intermediate result,
quotient and remainder.  I will discuss more fundamental  aspects
of  these two words together with the subject  of  floating-point
and scaling.
The  family-portrait  of  our  Sixteenbitters  shows  still  some
unknown  faces.  Here are {NEGATE} and {ABS}.  They both  perform
exactly  that kind of action,  you expect them to do  from  their
name.  {NEGATE} changes the sign of a number,  {ABS} returns  the
absolute  value of a number.  E.g.  18 {NEGATE} {.}   -18OK  -18
{NEGATE} {.}  18OK;        .
-18 {ABS} {.}  18OK 18 {ABS} {.}  18OK.  Look carefully at  the
output  of  the  examples.   Two  pairs  of  words  seem  to   be
superfluous:  {1-} {1+} and {2-} {2+}.  You may look upon them in
the  same  way  as  {2*}  and  {2/}.  They  perform  very  common
stackactions  and  as putting numbers on the  stack  is  somewhat
slowing down FORTH's speed (He thinks,  though),  these words are
especially designed for speed.  So 1 {+} is slower than {1+}. Not

noticeable  when  the plussing is done one time,  but  the  time-
saving aspect of {1+} becomes substantial if the operation has to
be carried out thousands and thousands of times.

UNSPOKEN

I  owe  you  some  explanation.  I didn't  want  to  disturb  the
procedure  of what was to be explained about 16-bit  numbers  too
much,  so  two  words were unspoken off:  {C@} and  {C!}  in  the
definition of {B.}.
For  now this will do.  {C@} extracts a byte value from the  word
{BASE}  and  put  that value TOS.  Which  value  depends  on  the
numberbase FORTH is working in: a 2 in binary, a 10 in decimal, a
16 in hexadecimal base. {C!} is the opposite of {C@}: it stores a
byte-value into a word.  So 5 {BASE} {C!} will put the value of 5
into the word {BASE}. The value has to be TOS.
I  invited  you  to define the word  {B.}.  If  you  accepted  my
invitation  the definition was put in the  dictionary.  But....if
you  disconnect    the powersupply or reset your  machine  you'll
have to reload FORTH.  You will then discover, that our {B.}-word
has disappeared from the dictionary.  If you want it back, you'll

have  to  define it anew.  There is of course a way  to  preserve
self-defined   words  on  disc.   Wait  for  the  editor  to   be
explained.......

Next  time we will discuss the stack's magic.  Two spells I  gave
already:  {DUP} and {SWAP}.  But there are some more. And we will
have a look at FORTH relational and logical operators  too....and
seeing  things double right now ?  We will discuss  double-length
arithmetic as well. Keep smiling !!

SUMMARY

FORTH's arithmetic takes place on the stack.  FORTH supplies  a
lot of arithmetic operators with specific functions.  Numbers are
16-bits (or 32-bits) long and integer.  Single-length or  single-
precision  arithmetic  deals  with  16-bits  numbers.   The  s.l.
arithmetic  operators  are  designed  to  work  on  s.l.  numbers
exclusively:  a  list  is  provided in this  part  two.  In  s.l.
arithmetic signed numbers range from -32768 to +32767  inclusive.
In  unsigned form s.l.  numbers range from 0 to 65535  inclusive.
Exceeding these limits will give unreliable results.  All signed
numbers are in two's complement form.
On  32-bit  stacks there is no distinction  between  single-  and
double-length numbers.  REMEMBER
Two's  complement    - The two's complement of a  number  is  the
exact equal absolute value but with opposite
sign.
Integer            -  An integer is a number with  no  fractional
parts. E.g. 123, 2, -365 are integers.
Numberbase         - A number is a complex symbol.  In daily life
we use decimal base.  Ten is the base.  To
compose a number there are two main points
to observe: the value of a figure, and the
place of that figure in  the  number.  The
place  is  calculated from right  (=0)  to
left. An example. Number 23456. The  6 has
a value of six and place  0.  The  decimal
value of 6 is now 6 * 10^0. Now 10^0=1. So
the 6 in place 0 is worth six. As for  the
5. The decimal value of the 5 is 5 * 10^1=
5*10=50. The 4: 4*10^2=4*100=400,  the  3:
3*10^3=3*1000=3000.    In   place  0   the
basenumber is raised to the power of 0, in
place 1 to the power of 1, in place  2  to
the power of 2 etc.  etc.  When you choose
another base, the one thing to  change  in
the example above is the 10.
E.g. we choose base 8,  octal base.  The 6
is 6*8^0=6*1=6.  The 5:  5*8^1=5*8=40. The
4: 4*8^2=4*64=256 etc. etc. You may change
to whatever base you like, the calculation
remains the same.  The  most  common bases
used are decimal,  binary and hexadecimal.
Dolly   Dots   -   A  worldfamous  (in  Holland,  though)  female
popgroup.
Colondefinition    - A colondefinition is the most common way  of
defining  new  words.  The  word  {:}  always
opens the definition, followed by a space and
the  name of the new word.  Then other  words
follow to define the action of the new word.
The last word always is {;}.
Aristotle - Greek philosofer (4th cent.  b.C.).  The quotation is
to be found in 'Nicomachean Ethics'.

_________________________________________________________________
|  word  |      stackaction         |   description             |
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
|   +    | (n1\n2 -- sum: n1+n2)    | Add                       |
|   -    | (n1\n2 -- dif: n1-n2)    | Subtract                  |
|   *    | (n1\n2 -- prd: n1*n2)    | Multiply                  |
|   /    | (n1\n2 -- quo: n1/n2)    | Divide (integer)          |
|  MOD   | (n1\n2 -- remainder )    | Remainder of n1/n2        |
| /MOD   | (n1\n2 -- rem\quo   )    | Leave quotient with       |
|        |                          | remainder beneath         |
|  */    | (n1\n2\n3 -- n1*n2/n3)   | Intermediate product n1*n2|
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
_________________________________________________________________
|  word  |      stacknotation       |   description             |
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
|        |                          | is stored as 32-bit number|
| */MOD  |(n1\n2\n3 -- rem\n1*n2/n3)| As */ but also leaves     |
|        |                          | remainder beneath         |
| NEGATE |    (n1 -- -n1)           | Change sign               |
|  ABS   |    (n1 -- |n1|)          | Absolute value            |
|  1+    |    (n1 -- n2)            | Add 1 to top stack item   |
|  1-    |    (n1 -- n2)            | Subtract 1 from top stack |
|        |                          | item                      |
|  2+    |    (n1 -- n2)            | Add 2 to top stack item   |
|  2-    |    (n1 -- n2)            | Subtract 2 from top stack |
|        |                          | item                      |
|  2*    |    (n1 -- n2)            | Fast multiply by 2        |
|  2/    |    (n1 -- n2)            | Fast divide by 2          |
|________|__________________________|___________________________|

EXTRAS

A very popular word in FORTH is FIG.  Although it is a FORTH-word
you never will encounter it in a dictionary.  It stands for FORTH
Interest Group.  This group exists to promote interest in and use
of FORTH.  The parent-group is found in the USA;  but almost each
country  has  its  own  branch.  Enquire  your  computerclub  for

FORTH Interest Group
PO Box 1105
San Carlos
Ca 94070
U.S.A.

Envelope (SAE)!!

EXERCISES

1.  Put (as many as you like) negative numbers on the stack.
Have them output by {B.}. Be sure {B.} is in the dictionary.
Mark the state of the 16th bit.
Clear the stack with help of {SP!}.   Repeat,  but this  time
with positive numbers. Again, mark the state of the 16th bit.
What can you tell now about signed numbers regarding the 16th
bit ? Explain why that bit is called the sign-bit !
2.  Remember  Starslash ?  On that subject I gave an example that
turned out to give false answers: 113 768 {*} 8 {/}.  Rewrite
this example to give the right answer, not using {*/}.
3.  Rewrite this formula:344 X 105 in R.P.N. in two ways.
35
4.  What is the remainder of: 576 X 861
15
5.  What is the unsigned equivalent of -986 ?
6.  Write the  next formula down in such a way, that all operands
are on one side and the operators on the other side:
(69 + 3) X 5  e.g. 1480 5 3 97 * + /
18

7.  {*/MOD}  has two 16-bit numbers put on the stack,  a quotient
and  a  remainder.   Which of them two is the higher  on  the
stack?
Use your brains, not the stacknotation !
8.  Subtract: 8 - 4, but don't use {-}. 9.  Explain the following
stacknotation: (n -- n^2). Here is the word, I wrote. :  QUAD
DUP * ;.
10. Write your own word of which the stacknotation is (n -- n^3).

Next time I'll give the solutions. Till then !!!

Disclaimer
The text of the articles is identical to the originals like they appeared in old ST NEWS issues. Please take into consideration that the author(s) was (were) a lot younger and less responsible back then. So bad jokes, bad English, youthful arrogance, insults, bravura, over-crediting and tastelessness should be taken with at least a grain of salt. Any contact and/or payment information, as well as deadlines/release dates of any kind should be regarded as outdated. Due to the fact that these pages are not actually contained in an Atari executable here, references to scroll texts, featured demo screens and hidden articles may also be irrelevant.