box.matto.nl
Enjoying Open Source Software

dc: a RPN commandline calculator

dc is a commandline calculater that uses reverse polish notation (RPN). RPN is an efficient way to calculate. In the seventees scientists and engineers choose the HP pocket calculators because of this. Those calculators worked with the RPN method.

By using RPN you don't need to enter parenthesis and, after getting used to it, the order in which you enter the operands and operations is more intuitive. So the use of RPN is more efficient and less error-prone.

RPN calculators work with a stack, where entries can be pushed and popped. Pushing puts a new entry at the top of the stack, popping removes an entry from the top of the stack.

Think of a stack like a pile of dishes in the kitchensink. You add a new dish to this stack by putting one on top and remove a dish by taking one from the top.

Adding the two numbers 4 and 3 works like this:

  • push the number 4 to the stack:
    The stack now contains one entry, the number 4
  • push the number 3 to the stack:
    The stack now contains two entries, the number 4 at the bottom and the number 3 at the top
  • give the "plus" command:
    The calculator now pops two values from the stack, first the top value (in our case 3), after which the next value on the stack becomes the top value.
    The calculator pops another values from the stack (in our cases 4) and do an addition of those two values. It than pushes the outcome of this operation to the stack

We can write this as:

4
3
+

Calculating 5 - ( 3 * 4 )

With RPN this kind of calculations become quite easy:

5
3
4
*
-

Explanation:

After pushing 5,3, and 4 our stack is, from top to bottom,

4
3
5

Now we do the "product" operation (*). The calculator pops the two top values (4 and 3) and pushes the product.

After this operation, our stack is, from top to bottom,

12
5

Now we do the "difference" operation (-). The calculator pops the two top values (12 and 5) and pushes the difference.

-7

Because the outcome of a operation is pushed back to the stack, we can continu calculating. Most of the time entering formula's in RPN follows the formula closer, compared to a 'normal' calculator, where we have to much more aware of where the parenthesis are.

Reverse polish notation in dc

To use dc directly, just enter 'dc' on the commandline. This will start dc and allows us to enter commands (there is no prompt).

Entering a number followed by Enter pushes the current number to the stack.

So, like the example above, we can just enter:

5
3
4
*
-

This will push the result (-7) to the stack. In order for us to see this, we have to give the command 'p', which will print the top value of the stack, without altering the stack.

Here are some things we can enter in dc:

Enter: pushes the current line to the stack
p:     prints the top value of the stack (without
       altering the stack)
f:     prints the entire stack (without
       altering the stack)

+:     pops two values from the stack and pushes
       the sum
-:     pops two values from the stack and pushed
       the difference
*:     pops two values from the stack and pushes
       the product
/:     pops two values from the stack and pushes
       the fraction
%:     pops two values from the stack and pushes
       the modulo value
^:     pops two values from the stack and pushes
       the exponatation
v:     pops one value from the stack and pushes
       the square root of that value

c:     clears the stack
d:     duplicates the top of the stack

Set the precision

In the default setting, dc will show the results without any decimal digits:

10
3
/
p
3

To change this, set your preferred precision number in the stack, like 3 and give the command k:

3
k

Now, test:

10
3
/
p
3.333

Using registers

dc gives us 256 named registers, 'a' to 'z'.

Pop to register

sa:    pops the value from the top of the stack and 
       put that in register 'a'.

Use register as stack

Sa:    pops the value from the top of the stack and
       pushes that on top of the stack of register 'a'.

Push a copy from register

la:    copies the value from the register 'a' and pushes
       that to the stack.

So, this operation will alter the stack.

Pop from register and push to stack

La:    pop the top value from the stack of register 'a' 
       and push that to the stack

Use a different output number base

You can view the number on top of the stack in different number base systems.

With the command "o" we switch to a different output number base. First put the number of the desired number-base on the stack, than enter 'o'.

Below we view some numbers in a 16-base and in 2-base:

16
o
254
p
FE
12
p
C
2
o
254
p
11111110
12
p
1100

There is more to dc

This was just a short introduction. We didn't touch things like creating a macro and storing it as a string in a register, looping and much more.

dc is a very old Unix utility, so there will be differences in current versions, like GNU and non-GNU. As always, read the very informative manpages.

The examples above were tested on a FreeBSD system.

I am grateful to Sergey Matveev who pointed me to dc on his webslite.

Resources

Tags: dc RPN