calc: RPN Tutorial
3.1.1 RPN Calculations and the Stack
------------------------------------
Calc normally uses RPN notation. You may be familiar with the RPN
system from Hewlett-Packard calculators, FORTH, or PostScript. (Reverse
Polish Notation, RPN, is named after the Polish mathematician Jan
Lukasiewicz.)
The central component of an RPN calculator is the “stack”. A
calculator stack is like a stack of dishes. New dishes (numbers) are
added at the top of the stack, and numbers are normally only removed
from the top of the stack.
In an operation like ‘2+3’, the 2 and 3 are called the “operands” and
the ‘+’ is the “operator”. In an RPN calculator you always enter the
operands first, then the operator. Each time you type a number, Calc
adds or “pushes” it onto the top of the Stack. When you press an
operator key like ‘+’, Calc “pops” the appropriate number of operands
from the stack and pushes back the result.
Thus we could add the numbers 2 and 3 in an RPN calculator by typing:
‘2 <RET> 3 <RET> +’. (The <RET> key, Return, corresponds to the <ENTER>
key on traditional RPN calculators.) Try this now if you wish; type
‘C-x * c’ to switch into the Calc window (you can type ‘C-x * c’ again
or ‘C-x * o’ to switch back to the Tutorial window). The first four
keystrokes “push” the numbers 2 and 3 onto the stack. The ‘+’ key
“pops” the top two numbers from the stack, adds them, and pushes the
result (5) back onto the stack. Here’s how the stack will look at
various points throughout the calculation:
. 1: 2 2: 2 1: 5 .
. 1: 3 .
.
C-x * c 2 <RET> 3 <RET> + <DEL>
The ‘.’ symbol is a marker that represents the top of the stack.
Note that the “top” of the stack is really shown at the bottom of the
Stack window. This may seem backwards, but it turns out to be less
distracting in regular use.
The numbers ‘1:’ and ‘2:’ on the left are “stack level numbers”. Old
RPN calculators always had four stack levels called ‘x’, ‘y’, ‘z’, and
‘t’. Calc’s stack can grow as large as you like, so it uses numbers
instead of letters. Some stack-manipulation commands accept a numeric
argument that says which stack level to work on. Normal commands like
‘+’ always work on the top few levels of the stack.
The Stack buffer is just an Emacs buffer, and you can move around in
it using the regular Emacs motion commands. But no matter where the
cursor is, even if you have scrolled the ‘.’ marker out of view, most
Calc commands always move the cursor back down to level 1 before doing
anything. It is possible to move the ‘.’ marker upwards through the
stack, temporarily “hiding” some numbers from commands like ‘+’. This
is called “stack truncation” and we will not cover it in this tutorial;
Truncating the Stack, if you are interested.
You don’t really need the second <RET> in ‘2 <RET> 3 <RET> +’.
That’s because if you type any operator name or other non-numeric key
when you are entering a number, the Calculator automatically enters that
number and then does the requested command. Thus ‘2 <RET> 3 +’ will
work just as well.
Examples in this tutorial will often omit <RET> even when the stack
displays shown would only happen if you did press <RET>:
1: 2 2: 2 1: 5
. 1: 3 .
.
2 <RET> 3 +
Here, after pressing ‘3’ the stack would really show ‘1: 2’ with ‘Calc:
3’ in the minibuffer. In these situations, you can press the optional
<RET> to see the stack as the figure shows.
(•) *Exercise 1.* (This tutorial will include exercises at various
points. Try them if you wish. Answers to all the exercises are located
at the end of the Tutorial chapter. Each exercise will include a
cross-reference to its particular answer. If you are reading with the
Emacs Info system, press ‘f’ and the exercise number to go to the
answer, then the letter ‘l’ to return to where you were.)
Here’s the first exercise: What will the keystrokes ‘1 <RET> 2 <RET> 3
<RET> 4 + * -’ compute? (‘*’ is the symbol for multiplication.) Figure
it out by hand, then try it with Calc to see if you’re right. 1
RPN Answer 1. (•)
(•) *Exercise 2.* Compute ‘2*4 + 7*9.5 + 5/4’ using the stack.
2 RPN Answer 2. (•)
The <DEL> key is called Backspace on some keyboards. It is whatever
key you would use to correct a simple typing error when regularly using
Emacs. The <DEL> key pops and throws away the top value on the stack.
(You can still get that value back from the Trail if you should need it
later on.) There are many places in this tutorial where we assume you
have used <DEL> to erase the results of the previous example at the
beginning of a new example. In the few places where it is really
important to use <DEL> to clear away old results, the text will remind
you to do so.
(It won’t hurt to let things accumulate on the stack, except that
whenever you give a display-mode-changing command Calc will have to
spend a long time reformatting such a large stack.)
Since the ‘-’ key is also an operator (it subtracts the top two stack
elements), how does one enter a negative number? Calc uses the ‘_’
(underscore) key to act like the minus sign in a number. So, typing ‘-5
<RET>’ won’t work because the ‘-’ key will try to do a subtraction, but
‘_5 <RET>’ works just fine.
You can also press ‘n’, which means “change sign.” It changes the
number at the top of the stack (or the number being entered) from
positive to negative or vice-versa: ‘5 n <RET>’.
If you press <RET> when you’re not entering a number, the effect is
to duplicate the top number on the stack. Consider this calculation:
1: 3 2: 3 1: 9 2: 9 1: 81
. 1: 3 . 1: 9 .
. .
3 <RET> <RET> * <RET> *
(Of course, an easier way to do this would be ‘3 <RET> 4 ^’, to raise 3
to the fourth power.)
The space-bar key (denoted <SPC> here) performs the same function as
<RET>; you could replace all three occurrences of <RET> in the above
example with <SPC> and the effect would be the same.
Another stack manipulation key is <TAB>. This exchanges the top two
stack entries. Suppose you have computed ‘2 <RET> 3 +’ to get 5, and
then you realize what you really wanted to compute was ‘20 / (2+3)’.
1: 5 2: 5 2: 20 1: 4
. 1: 20 1: 5 .
. .
2 <RET> 3 + 20 <TAB> /
Planning ahead, the calculation would have gone like this:
1: 20 2: 20 3: 20 2: 20 1: 4
. 1: 2 2: 2 1: 5 .
. 1: 3 .
.
20 <RET> 2 <RET> 3 + /
A related stack command is ‘M-<TAB>’ (hold <META> and type <TAB>).
It rotates the top three elements of the stack upward, bringing the
object in level 3 to the top.
1: 10 2: 10 3: 10 3: 20 3: 30
. 1: 20 2: 20 2: 30 2: 10
. 1: 30 1: 10 1: 20
. . .
10 <RET> 20 <RET> 30 <RET> M-<TAB> M-<TAB>
(•) *Exercise 3.* Suppose the numbers 10, 20, and 30 are on the
stack. Figure out how to add one to the number in level 2 without
affecting the rest of the stack. Also figure out how to add one to the
number in level 3. 3 RPN Answer 3. (•)
Operations like ‘+’, ‘-’, ‘*’, ‘/’, and ‘^’ pop two arguments from
the stack and push a result. Operations like ‘n’ and ‘Q’ (square root)
pop a single number and push the result. You can think of them as
simply operating on the top element of the stack.
1: 3 1: 9 2: 9 1: 25 1: 5
. . 1: 16 . .
.
3 <RET> <RET> * 4 <RET> <RET> * + Q
(Note that capital ‘Q’ means to hold down the Shift key while typing
‘q’. Remember, plain unshifted ‘q’ is the Quit command.)
Here we’ve used the Pythagorean Theorem to determine the hypotenuse
of a right triangle. Calc actually has a built-in command for that
called ‘f h’, but let’s suppose we can’t remember the necessary
keystrokes. We can still enter it by its full name using ‘M-x’
notation:
1: 3 2: 3 1: 5
. 1: 4 .
.
3 <RET> 4 <RET> M-x calc-hypot
All Calculator commands begin with the word ‘calc-’. Since it gets
tiring to type this, Calc provides an ‘x’ key which is just like the
regular Emacs ‘M-x’ key except that it types the ‘calc-’ prefix for you:
1: 3 2: 3 1: 5
. 1: 4 .
.
3 <RET> 4 <RET> x hypot
What happens if you take the square root of a negative number?
1: 4 1: -4 1: (0, 2)
. . .
4 <RET> n Q
The notation ‘(a, b)’ represents a complex number. Complex numbers are
more traditionally written ‘a + b i’; Calc can display in this format,
too, but for now we’ll stick to the ‘(a, b)’ notation.
If you don’t know how complex numbers work, you can safely ignore
this feature. Complex numbers only arise from operations that would be
errors in a calculator that didn’t have complex numbers. (For example,
taking the square root or logarithm of a negative number produces a
complex result.)
Complex numbers are entered in the notation shown. The ‘(’ and ‘,’
and ‘)’ keys manipulate “incomplete complex numbers.”
1: ( ... 2: ( ... 1: (2, ... 1: (2, ... 1: (2, 3)
. 1: 2 . 3 .
. .
( 2 , 3 )
You can perform calculations while entering parts of incomplete
objects. However, an incomplete object cannot actually participate in a
calculation:
1: ( ... 2: ( ... 3: ( ... 1: ( ... 1: ( ...
. 1: 2 2: 2 5 5
. 1: 3 . .
.
(error)
( 2 <RET> 3 + +
Adding 5 to an incomplete object makes no sense, so the last command
produces an error message and leaves the stack the same.
Incomplete objects can’t participate in arithmetic, but they can be
moved around by the regular stack commands.
2: 2 3: 2 3: 3 1: ( ... 1: (2, 3)
1: 3 2: 3 2: ( ... 2 .
. 1: ( ... 1: 2 3
. . .
2 <RET> 3 <RET> ( M-<TAB> M-<TAB> )
Note that the ‘,’ (comma) key did not have to be used here. When you
press ‘)’ all the stack entries between the incomplete entry and the top
are collected, so there’s never really a reason to use the comma. It’s
up to you.
(•) *Exercise 4.* To enter the complex number ‘(2, 3)’, your friend
Joe typed ‘( 2 , <SPC> 3 )’. What happened? (Joe thought of a clever
way to correct his mistake in only two keystrokes, but it didn’t quite
work. Try it to find out why.) 4 RPN Answer 4. (•)
Vectors are entered the same way as complex numbers, but with square
brackets in place of parentheses. We’ll meet vectors again later in the
tutorial.
Any Emacs command can be given a “numeric prefix argument” by typing
a series of <META>-digits beforehand. If <META> is awkward for you, you
can instead type ‘C-u’ followed by the necessary digits. Numeric prefix
arguments can be negative, as in ‘M-- M-3 M-5’ or ‘C-u - 3 5’. Calc
commands use numeric prefix arguments in a variety of ways. For
example, a numeric prefix on the ‘+’ operator adds any number of stack
entries at once:
1: 10 2: 10 3: 10 3: 10 1: 60
. 1: 20 2: 20 2: 20 .
. 1: 30 1: 30
. .
10 <RET> 20 <RET> 30 <RET> C-u 3 +
For stack manipulation commands like <RET>, a positive numeric prefix
argument operates on the top N stack entries at once. A negative
argument operates on the entry in level N only. An argument of zero
operates on the entire stack. In this example, we copy the
second-to-top element of the stack:
1: 10 2: 10 3: 10 3: 10 4: 10
. 1: 20 2: 20 2: 20 3: 20
. 1: 30 1: 30 2: 30
. . 1: 20
.
10 <RET> 20 <RET> 30 <RET> C-u -2 <RET>
Another common idiom is ‘M-0 <DEL>’, which clears the stack. (The
‘M-0’ numeric prefix tells <DEL> to operate on the entire stack.)