dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
NAME
dc -- arbitrary precision desk calculator
SYNOPSIS
dc [file]
DESCRIPTION
dc is a desk calculator program that takes input in reverse Pol-
ish notation (see Reverse Polish Notation later in this man
page). If you do not specify a file on the command line, dc
reads input from the standard input; otherwise, it reads input
from the file and then from the standard input (if there is no
quit command in the file). dc sends output to the standard out-
put.
There are several types of input:
(a) Numbers are sequences of digits, possibly containing a deci-
mal point. Numbers can also contain the uppercase charac-
ters A through F standing for the hexadecimal (base 16)
digits greater than ten; for more on hexadecimal, see the
section on Numbers in Different Bases. Do not break up a
number with spaces or commas; for example, you must write
1000000, not 1,000,000. To create a negative number, put an
underscore (_) immediately before the first digit of the
number. Do not use a minus sign (-) to indicate a negative
number; the minus sign has an entirely different meaning in
dc input.
(b) Strings are sequences of characters, enclosed in square
brackets. For example, [abc] is a string which contains the
characters abc.
(c) Operators are symbols or characters telling dc to perform
some operation; for example, adding two numbers together.
(d) Register names are single characters. You may use any char-
acter as a register name. An uppercase letter is not the
same as the corresponding lowercase one, so register a is
different from register A. A register is a place where dc
can store a number or a string; it is similar to a variable
in a programming language. Typically, you use registers to
store values that you want to remember for later use.
(e) Array names follow the same rules as register names. See
Array Operations later in this man page for more details.
You must separate adjacent numbers with at least one white space
character. (The white space characters for dc are the blank, the
horizontal tab, and the newline.) You do not need to separate
other pieces of input from one another, but putting in white
space characters makes the input more readable. As exceptions,
register names and array names must immediately follow the
1
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
operator that tells what you want to do with the register or
array (as described later in this man page). If you put a white
space character after an operator that expects a register or
array name, dc assumes the white space character to be the name.
Reverse Polish Notation
To use dc you must understand reverse Polish notation. This is a
way to write arithmetic expressions. The form is a bit tricky
for people to understand, since it is geared towards making it
easy for the computer to perform calculations; however, most
people can get used to the notation with a bit of practice.
Reverse Polish notation stores values in a stack. A stack of val-
ues is just like a stack of books: one value is placed on top of
another. When you want to perform a calculation, the calculation
uses the top numbers on the stack.
For example, here's a typical addition operation:
1 2 +
When dc reads a number or a string, it just puts the value onto
the stack. Thus 1 goes on the stack, then 2 goes on the stack.
When you put a value onto the stack, we say that you push it onto
the stack. When dc reads the operator +, it takes the top two
values off the stack, adds them, then pushes the result back onto
the stack. After this addition, the stack contains
3
As another example, consider
2 3 4 + *
(The * stands for multiplication.) dc begins by pushing the
three numbers onto the stack. When it finds the +, it takes the
top two numbers off the stack and adds them. (Taking a value off
the stack is called popping the stack.) dc then pushes the
result of the addition back onto the stack in place of the two
numbers. Thus the stack contains
2 7
When dc finds the * operator, it again pops the top two values
off the stack. It multiplies them, then pushes the result back
onto the stack, leaving
14
The following list gives a few more examples of reverse Polish
expressions. After each, we show the contents of the stack, in
parentheses.
2
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
7 2 - (5)
2 7 - (-5)
12 3 / (4)
_12 3 / (-4)
4 5 + 2 * (18)
4 5 2 + * (28)
4 5 2 * - (-6)
If you are experimenting with dc to see how this works, you can
type p to print out the top value on the stack and f to print out
the full stack.
The Scaling Factor
One of dc's great virtues is its ability to deal with numbers of
arbitrary size and precision -- dc is not constrained by the
hardware's restrictions on number size or precision.
Many arithmetic calculations use a scaling factor, an integer
greater than or equal to zero, and strictly less than 100. The
scaling factor affects how many decimal places dc uses when mak-
ing calculations.
The default scaling factor begins at zero (no decimal places).
This can be confusing; for example, if you try
1 2 / p
to divide 1 by 2 and print the result, dc prints 0. The real
answer is 0.5 but a scaling factor of 0 tells dc not to keep
track of fractions when doing arithmetic.
You can set a different default scaling factor with the k opera-
tion. This pops the top value from the stack and sets that value
to the new default scaling factor. For example,
4 k
sets the default scaling factor to 4. Now if you try
1 2 / p
the result is .5000.
As our discussion of arithmetic operations points out, the number
of decimal places in the operands also affects the number of dec-
imal places in the answer. Thus the scaling factor is not the
only influence on the precision of the calculations.
The K operation pushes the current default scaling factor onto
the stack.
3
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
Basic Operators
The following list is the operators recognized by dc and the
effects that they have.
+ pops the top two values from the stack, adds them, then
pushes the result onto the stack. The number of decimal
places in the result is the maximum number of decimal places
in the two operands; the scaling factor has no effect.
- pops the top two values from the stack, subtracts the first
popped from the second, then pushes the result onto the
stack. The number of decimal places in the result is the
maximum number of decimal places in the two operands; the
scaling factor has no effect.
* pops the top two values from the stack, multiplies them,
then pushes the result onto the stack. dc normally sets the
number of decimal places in the result to the sum of the
decimal places in the two operands; if this is larger than
the scaling factor and also larger than the number of deci-
mal places in both individual operands, the number of deci-
mal places in the result is the largest of the scaling fac-
tor or the number of decimal places in either operand.
/ pops the top two values from the stack, divides the second
popped by the first, then pushes the result onto the stack.
The number of decimal places in the result is equal to the
scaling factor.
% pops the first two values from the stack, divides the second
popped by the first, then pushes the remainder onto the
stack. (Mathematically, A B % calculates A modulo B.) dc
determines the number of decimal places in the result by the
result of the division.
^ pops the first two values from the stack, calculates the
second popped to the power of the first, then pushes the
result onto the stack. For example,
2 3 ^
leaves the value 8 on the stack. The exponent value must be
an integer (that is, with no decimal places). The scaling
factor of the result is the scaling factor you get if the
base was multiplied the appropriate number of times.
c clears the stack (that is, pops all the values off and dis-
cards them).
d duplicates the value on top of the stack. For example,
d *
4
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
duplicates the top value, then does a multiplication. The
result is that you square the value on top of the stack. As
another example, you can use d to save the value on top of
the stack in a register while keeping a copy of the value on
the stack; in this case, you'd use d to duplicate the top
value, then use s to pop the duplicate value into a regis-
ter.
f prints all values on the stack, from top to bottom. (It
does not print the contents of the registers.)
K pushes the current default scaling factor onto the stack.
k pops the top value off the stack and uses it as the default
scaling factor (see the section on The Scaling Factor).
Lx pops the top value off the register stack x (see the S com-
mand) and pushes that value onto the main stack. If the
register has never contained a value, dc treats this as an
error. (Contrast this behavior with the way that the lx
operator works.) This operator also pops the array compo-
nent of the specified register. See the Array Operations
section for more information.
lx takes the value from register x and pushes it onto the
stack. This does not change the value of the register. If
the register has never contained a value, dc puts a value of
zero on the stack.
P pops the top value off the stack, prints it as a string, and
then discards it. If the value is a string, dc prints it as
such. If it is a number, dc prints the ASCII character with
that value.
p prints the top value on the stack. The value remains on the
stack.
q quits a dc session; however, see the Executing Strings sec-
tion for an exception.
Sx pops the top value off the stack and pushes this value onto
the register x as if the register itself were another stack.
In this way, you can use a single register to hold a
sequence of values. This operation also pushes the array
component of the register onto the register's stack. See
the Array Operations section for more information.
sx pops the top value off the stack and stores it in the regis-
ter x. For example, sa pops the stack and stores the value
in register a.
v replaces the top value on the stack with its square root.
dc ignores the scaling factor when performing calculations
5
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
to find the square root. The number of decimal places in
the result is the maximum of the number of decimal places in
the original value or the scaling factor.
X replaces the value on the top of the stack with the number
of decimal places in the number.
x executes a string. See Executing Strings.
Z replaces the number on the top of the stack with its length
(that is, the number of digits in the number).
Note: dc ignores the minus sign and decimal point when cal-
culating this value, so that 12345 and _123.45 have the same
length.
z determines how many values are currently on the stack, then
pushes that number onto the stack.
Numbers in Different Bases
Programmers often find it useful to perform arithmetic with num-
bers in bases other than ten, for example, octal (base 8) or hex-
adecimal (base 16) numbers. Several commands help make this pos-
sible.
I pushes the current input base onto the stack.
i pops the top value of the stack and uses this as the base
when interpreting further input. For example,
8i
tells dc that from now on, it is to interpret input numbers
as octal values. For example, if you type 10 as input, dc
interprets it as an octal number, equal to 8 (base ten).
Note: You can use the characters A through F to input hexa-
decimal digits regardless of the base.
O pushes the current output base onto the stack.
o pops the top value of the stack and uses this as the base
when printing output. For example,
16o
tells dc to print subsequent numbers in hexadecimal format.
Note: The input and output bases can be different; for
example, you may find this convenient if you want to convert
input in one base to output in another.
6
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
You can make the output base larger than 16. In this case, dc
prints each digit as a decimal value and separates them with a
single space. For example,
1000 o
123456789 p
prints
123 456 789
This sets the output base to 1000, where digits are decimal val-
ues from 0 through 999. As a result, dc breaks up all values
into one or more chunks with three digits per chunk. Using out-
put bases that are large powers of ten, you can put your output
in columns; for example, many users find that 100000 makes a good
output base because dc groups numbers into chunks of five digits
each.
dc outputs long numbers with a maximum of 70 characters per line.
If a number is longer than this, dc puts a backslash \ at the end
of the line, indicating that the number continues on the next
line.
dc always prints a value of zero as 0, regardless of the output
base and regardless of the number of decimal places that are nor-
mally attached to the value.
Some people have trouble figuring out how to put the input base
back to base ten after working in some other base.
A i
always works, since A stands for the hexadecimal digit ten.
The maximum output base is the maximum integer value that the
hardware can represent.
Executing Strings
A string is any sequence of characters. In particular, a string
may consist of a sequence of dc commands.
The x command pops the top value from the stack and executes it
as if it were a string containing dc commands. For example, con-
sider the following code:
[lapP lbpP]sz
This pushes the string inside the square brackets onto the stack,
and then pops it into register z. From this point onward, the
command
lzx
7
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
pushes the string in z onto the stack, then execute the commands
inside the string. The sequence of commands lapP pushes the
value of register a onto the stack, prints it, then pops the
value off again. The sequence of commands lbpP does the same for
register b. The result is that we can use lzx to print the cur-
rent contents of registers a and b any time we want.
There are several other commands for executing strings:
>x pops two values off the stack. If the first popped value is
greater than the second, dc executes the contents of regis-
ter x as a string of commands. As an example,
la lb >z
executes the string in register z if the contents of regis-
ter b are greater than the contents of register a.
!>x pops two values off the stack. If the first popped value is
not greater than the second, dc executes the contents of
register x as a string of commands.
<x pops two values off the stack. If the first popped value is
less than the second, dc executes the contents of register x
as a string of commands.
!<x pops two values off the stack. If the first popped value is
not less than the second, dc executes the contents of regis-
ter x as a string of commands.
=x pops two values off the stack. If the first popped value is
equal to the second, dc executes the contents of register x
as a string of commands.
!=x pops two values off the stack. If these two values are not
equal, dc executes the contents of register x as a string of
commands.
One string may execute another. For example, a string being exe-
cuted via the x command may contain a > construction to execute a
register string if the condition holds true. In this case, dc
executes the new string, then returns to the old string to con-
tinue executing where it left off. A string may execute a string
which executes another string, and so on. Because of this possi-
bility, dc keeps a stack of the strings that it is currently exe-
cuting.
When dc finds a q command inside a string being executed, it
doesn't quit dc. Instead, it quits executing the current string,
plus the string that caused the execution of the current string.
In other words, it pops two strings off the currently executing
stack.
8
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
To see why you want to quit the two most recent strings, consider
the following example.
[q]sy
loads a quit command into register y. Now, we might use something
like
[... la lb >y ...]
to quit in the middle of the string if the value in register b is
greater than the value in register a. The command >y executes the
command string in register y if the condition is true; if the
quit command in y only stopped one command string, it would quit
executing the commands from y and go right back to executing the
main command string. To be able to use this technique to quit
the main command string, the q command must pop two command
strings.
The Q (uppercase) command is a variation on the simple q command.
Q pops the top number off the (value) stack and stops execution
of that many currently executing strings. For example,
3Q
stops the three most recent executing strings.
Array Operations
As noted previously, arrays are similar to registers in that they
have names consisting of a single character. However, a regis-
ter's array values are independent of it's scalar value; the
array element X[1] for example, is different than the scalar X.
An array is just a list of values. Values in the list are
referred to by number; for example, you can ask for the 12th
value in the list. The numbers used to refer to values are
called the subscripts of the array. The beginning of the list
has the subscript 0 and the maximum subscript for any array is
2047.
There are two array operations:
:x stores a value in array x. The operation begins by popping a
number off the stack and uses it as the subscript into the
array. dc then pops another value off the stack and stores
this value in the array using the given subscript.
;x obtains a value from the array x. dc pop the top number off
the stack to use as a subscript into the array. It then
places the value found at that subscript on the stack. The
operation does not affect the value inside the array; it
just takes a copy of the value.
9
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
If you use ; to obtain a value from an array, but you have not
yet used : to store a value in that position, dc automatically
puts a zero onto the stack (as if there were a zero in that posi-
tion).
In an earlier section, the S and L operators were used to push
and pop the scalar value of a register onto the register's stack.
These operators also push and pop the array component of a regis-
ter. This is done at the same time that the scalar values are
being pushed or popped with some differences in the details of
how operations work. Where L popped the top of the register's
scalar stack onto the main stack, the array operation simply pops
the top of the register's array stack then discards the result.
Where S popped the top of the main stack and pushed it onto the
register's scalar stack, the array operation simply hides the
current array values. Again, both the scalar and array operations
are caused by the same operator at the same time. The following
example shows how the S and L operations can be used to save or
hide the scalar and array values of a register. The operations
11 sa 12 1 :a la p 1 ;a p c
store 11 in a and 12 in a[1] then print the two values and
finally clear the main stack. The register a now has the scalar
value 11 and the array element a[1] now has the value 12. Next,
the operations
0 Sa la p 1 ;a p
save the current array and scalar values associated with the reg-
ister and print the new values for a and a[1] (which are now
zero). The old array and scalar values of the register have been
saved on the register's stack. You can change the value of the
register or any of the array elements without affecting these
saved values. To restore the old values, execute
La la p 1; a p
This pops the current array and scalar values off of the register
stack thus making the old values visible again. The restored val-
ues are then printed.
10
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
Other Commands
!command
executes the rest of the line as a system command. For
example,
!cp file1 file2
executes the given cp command.
? reads an input line from the input source (for example, the
terminal) and executes that line. This is useful when you
are executing a command string but want to obtain input in
the middle of the string.
EXAMPLE
The following sequence of commands prints out the first 12 ele-
ments of the Fibonacci sequence. In this sequence, the first two
values are 1, and each subsequent value is the sum of the previ-
ous two values. Registers a and b hold the two most recent val-
ues of the sequence; new values are calculated in the stack.
Register z holds the code needed to calculate new values, and
register c holds a count of how many values have been printed.
1 sa
1 sb
2 sc
[la lb + p lb sa sb lc 1 + d sc 13 >z] sz
la p sx lp p sx lz x
The first three lines set up registers a and b with the value 1,
and c with the count of values that have already been calculated
(the first two). The next line loads z with the main code to
execute. This code loads the values in a and b, adds them and
prints the result, moves the value of b to a, then saves the
newly calculated value in b. The count in c is then incremented;
the commands
d sc
make a duplicate copy of the count and save this duplicate back
in c. The final part of the code checks the count to see if it is
less than 13; if this is true, the contents of z are executed
again to get the next value. The final line in the program
prints the first two values of the sequence and then executes the
code in z.
11
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
DIAGNOSTICS
Possible exit status values are:
0 Successful completion.
1 An error occurred.
Messages
Message: can not execute number
Cause: You attempted to use the x operator to execute a
string, but the value on the top of the stack was a
number.
Action: Only use the x operator when there is a string on top
of the stack.
Message: command too long
Cause: You specified a command line to pass to the system with
the ! operator that was longer than 1000 bytes.
Action: Use a shorter command line.
Message: divide by 0
Cause: You attempted to divide by 0.
Action: Do not divide by zero.
Message: empty stack
Cause: You attempted an operation that required popping a
value from the stack, but the stack was empty.
Action: Push a value onto the stack and try the operation
again.
Message: exponent must be an integer from 0 to max
Cause: When using the ^ operator, the second value popped from
the stack (the exponent) was not an integer or was not
in the range 0 to max.
Action: Make sure that the value which is to be used as the
exponent is an integer in the range 0 to max.
Message: filename: system error
Cause: See syserror(3).
Action: See syserror(3).
Message: index too big
Cause: You attempted to use an array index that was greater
than 2047.
Action: Use an array index that is less than or equal to 2047.
Message: input radix too big
Cause: You specified an input radix (base) that is too large
for dc to handle.
Action: Specify a smaller input radix.
12
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
Message: negative argument to Q
Cause: You attempted to use the Q operator but the value on
the top of the stack was negative. Q cannot take a
negative argument.
Action: Make sure that the stack has a positive number on top
when using the Q operator.
Message: negative index
Cause: You attempted to use a negative number as an array
index.
Action: Use a positive number as an array index.
Message: number expected, string found
Cause: When popping a value from the stack, dc expected a num-
ber but a string value was found.
Action: Make sure that the stack contains the proper type of
value when performing operations using the stack.
Message: numerical constant is too long
Cause: You specified a numerical constant that had more than
1000 digits.
Action: Use a numerical constant with less than 1000 digits.
Message: oct_num is unimplemented
Cause: You specified a character which is not a currently
implemented operators. oct_num is the octal value of
the character.
Action: See the DESCRIPTION section of this man page for a list
of valid dc operators.
Message: out of memory (fatal)
Cause: dc ran out of system resources.
Action: Free up some resources, check for infinite recursion
when executing strings, and make sure information is
not being left on the stack.
Message: output radix too big
Cause: You specified an output radix that is too large for dc
to handle.
Action: Specify a smaller output radix.
Message: readstk?
Cause: You attempted to pop too many values off the stack with
the Q operator.
Action: Make sure that the top value on the stack is not
greater than the number of currently executing strings.
Message: save: args
Cause: You attempted to use the s or S operator when there was
no value on the stack.
Action: Make sure that there is at least one value on the stack
before trying to use the s and S commands.
13
dc(1) MPE/iX Shell and Utilities dc(1)
______________________________________________________________________
Message: scale too big
Cause: You specified a scaling factor that was too large for
dc to handle.
Action: Specify a smaller scaling factor.
Message: sqrt of negative number
Cause: You attempted to take the square root of a negative
number.
Action: Only use the v (square root) operator on positive num-
bers.
Message: stack too deep
Cause: You attempted to put more values on the stack than it
was able to hold. The maximum size of the stack is
limited by the size of the maximum integer your system
can represent.
Action: Check for uncontrolled recursion.
Message: string is too long
Cause: You specified a string that is too long for dc to
handle.
Action: Split the string into smaller strings.
LIMITS
Maximum array index: 2047.
Maximum exponent in an exponentiation operation: 9999.
Maximum input buffer size (line length): 1000 characters.
Maximum scaling factor: 99.
Maximum stack depth: MAXINT (that is, the size of the largest
positive integer that can be supported by the hardware).
PORTABILITY
UNIX System V.
MPE/iX NOTES
For information on how the current MPE/iX implementation may
affect the operation of this utility, see Appendix A, MPE/iX
Implementation Considerations.
SEE ALSO
bc(1)
14