Arithmetic |
Great joy can be derived from simply moving numbers around on a stack.
Eventually, however, you'll want to do something useful with them. This section
describes how to perform arithmetic operations in Forth.
A D V E R T I S E M E N T
The Forth arithmetic operators work on the numbers currently on top of the
stack. If you want to add the top two numbers together, use the Forth word +
, pronounced "plus". Enter:
2 3 + .
2 3 + 10 + .
This style of expressing arithmetic operations is called Reverse Polish
Notation, or RPN. It will already be familiar to those of you with HP
calculators. In the following examples, I have put the algebraic equivalent
representation in a comment.
Some other arithmetic operators are - * / . Enter:
30 5 - . ( 25=30-5 )
30 5 / . ( 6=30/5 )
30 5 * . ( 150=30*5 )
30 5 + 7 / . \ 5=(30+5)/7
Some combinations of operations are very common and have been coded in assembly
language for speed. For example, 2* is short for 2 * . You should use
these whenever possible to increase the speed of your program. These include:
1+ 1- 2+ 2- 2* 2/
Try entering:
10 1- .
7 2* 1+ . ( 15=7*2+1 )
One thing that you should be aware of is that when you are doing division with
integers using / , the remainder is lost. Enter:
15 5 / .
17 5 / .
This is true in all languages on all computers. Later we will examine /MOD
and MOD which do give the remainder.
Defining a New Word
It's now time to write a small program in Forth. You can do this by
defining a new word that is a combination of words we have already learned.
Let's define and test a new word that takes the average of two numbers.
We will make use of two new words, : ( "colon"), and ; (
"semicolon") . These words start and end a typical Forth definition.
Enter:
: AVERAGE ( a b -- avg ) + 2/ ;
Congratulations. You have just written a Forth program. Let's look more closely
at what just happened. The colon told Forth to add a new word to its list of
words. This list is called the Forth dictionary. The name of the new word will
be whatever name follows the colon. Any Forth words entered after the name will
be compiled into the new word. This continues until the semicolon is reached
which finishes the definition.
Let's test this word by entering:
10 20 AVERAGE . ( should print 15 )
Once a word has been defined, it can be used to define more words. Let's write a
word that tests our word.. Enter:
: TEST ( --) 50 60 AVERAGE . ;
TEST
Try combining some of the words you have learned into new Forth definitions of
your choice. If you promise not to be overwhelmed, you can get a list of the
words that are available for programming by entering:
WORDS
Don't worry, only a small fraction of these will be used directly in your
programs.
More Arithmetic
When you need to know the remainder of a divide operation. /MOD will return the
remainder as well as the quotient. the word MOD will only return the remainder.
Enter:
0SP
53 10 /MOD .S
0SP
7 5 MOD .S
Two other handy words are MIN and MAX . They accept two numbers
and return the MINimum or MAXimum value respectively. Try entering the
following:
56 34 MAX .
56 34 MIN .
-17 0 MIN .
Some other useful words are:
ABS ( n -- abs(n) , absolute value of n )
NEGATE ( n -- -n , negate value, faster then -1 * )
LSHIFT ( n c -- n<<c , left shift of n )
RSHIFT ( n c -- n>>c , logical right shift of n )
ARSHIFT ( n c -- n>>c ) , arithmetic right shift of n )
ARSHIFT or LSHIFT can be used if you have to multiply quickly by a power of 2
. A right shift is like doing a divide by 2. This is often faster than doing a
regular multiply or divide. Try entering:
: 256* 8 LSHIFT ;
3 256* .
Arithmetic Overflow
If you are having problems with your calculation overflowing the 32-bit
precision of the stack, then you can use */ . This produces an
intermediate result that is 64 bits long. Try the following three methods of
doing the same calculation. Only the one using */ will yield the correct answer,
5197799.
34867312 99154 * 665134 / .
34867312 665134 / 99154 * .
34867312 99154 665134 */ .
Convert Algebraic Expressions to Forth
How do we express complex algebraic expressions in Forth? For example: 20 + (3 *
4)
To convert this to Forth you must order the operations in the order of
evaluation. In Forth, therefore, this would look like:
3 4 * 20 +
Evaluation proceeds from left to right in Forth so there is no ambiguity.
Compare the following algebraic expressions and their Forth equivalents: (Do
not enter these!)
(100+50)/2 ==> 100 50 + 2/
((2*7) + (13*5)) ==> 2 7 * 13 5 * +
If any of these expressions puzzle you, try entering them one word at a time,
while viewing the stack.