Est. 1991 Intermediate

GNU Desk Calculator

The GNU Project implementation of the stack-based, arbitrary-precision dc calculator language, distributed alongside GNU bc since the early 1990s and the dc binary present on virtually every GNU/Linux system.

Created by Philip A. Nelson (initial GNU implementation), with subsequent GNU bc maintainers

Paradigm Procedural, Stack-based, Reverse Polish Notation
Typing Untyped (arbitrary-precision numbers and string registers)
First Appeared 1991
Latest Version Bundled with recent GNU bc releases (reportedly 1.08.x as of 2025)

GNU Desk Calculator (dc) is the GNU Project’s implementation of the venerable Unix dc language — a stack-based, arbitrary-precision calculator that operates in reverse Polish notation. First distributed in 1991 as part of Philip A. Nelson’s GNU bc release, GNU dc gave the GNU/Linux ecosystem a free-software replacement for the AT&T dc utility that had shipped with Unix since 1971. Today GNU dc is the dc binary present on essentially every Linux distribution, installed as a companion to GNU bc from the same bc source package.

For the history of the dc language itself — its 1971 origin at Bell Labs, its relationship to bc, and the alternative implementations (notably OpenBSD’s rewrite by Otto Moerbeek) — see the dc encyclopedia page. This page focuses specifically on the GNU implementation.

Origins

By the late 1980s, the GNU Project’s effort to produce a fully free-software Unix-like system required free replacements for every standard Unix utility, including the small but ubiquitous calculator tools bc and dc. The AT&T originals were not free software, and GNU/Linux distributions assembled in the early 1990s could not legally redistribute them.

Philip A. Nelson took on the bc/dc replacement task and released the first GNU bc in 1991. Although the original Bell Labs bc had been a preprocessor that compiled to dc postfix and shelled out to dc for execution, Nelson chose a different architecture for the GNU rewrite: GNU bc would be a self-contained bytecode interpreter with no runtime dependency on dc. GNU dc was therefore created as a separate, independent program in the same source distribution — useful on its own, but no longer required for bc to function.

This is the inverse of the historical relationship: in the Bell Labs lineage, bc was a front-end to dc; in the GNU lineage, dc is a stand-alone sibling of bc, both built from the same source tree but neither calling into the other.

The dc Language in the GNU Implementation

GNU dc accepts the classical dc command set — single-character operators acting on a stack of arbitrary-precision numbers — together with a number of GNU-specific extensions. The basic vocabulary is familiar to anyone who has used an HP RPN calculator:

CommandMeaning
<digits>Push a number onto the stack
+ - * / %Pop two operands, push the result
^Exponentiation
vSquare root (pop one, push its root)
pPrint the top of stack (without popping)
nPrint and pop
fPrint the entire stack
cClear the stack
dDuplicate the top of stack
rSwap (reverse) the top two values
kSet the precision (scale) from the top of stack
i oSet the input and output radix
s_X, l_XStore to / load from named register X
[ ... ]Push a string
xExecute the string at top of stack as a dc program

These are the core operations specified by the historical dc, and GNU dc implements them all.

GNU Extensions

Beyond the historical command set, GNU dc adds several features that are not present in the original AT&T dc and not always present in BSD-lineage rewrites:

  • Larger register namespace. Registers are addressed by character; GNU dc treats each register as itself a stack, so the S_X and L_X commands push and pop the entire register, not just overwrite it.
  • Comparison and conditional execution. <, >, =, !<, !>, != followed by a register name execute the macro stored in that register if the comparison of the top two stack elements is true.
  • ? for reading input. Reads a line from standard input and executes it as dc code, allowing macros that prompt the user.
  • # line comments. GNU dc supports # to end-of-line comments — convenient for any non-trivial dc program saved to a file.
  • -e and -f command-line flags. Allow expressions and program files to be passed without piping through standard input.

These extensions, particularly registers-as-stacks and the conditional-execution commands, make GNU dc Turing-complete in a way that is easy to actually use; the classic dc factorial and Fibonacci macros rely on them.

Architecture

GNU dc is implemented in C and, like GNU bc, performs all arithmetic in decimal rather than binary. Numbers are represented as arrays of decimal digits with an associated scale (number of fractional digits), and operations are carried out by an arbitrary-precision arithmetic library shared with GNU bc. This is what makes dc safe for financial calculations and reproducibly identical across platforms — at the cost of being slower than hardware floating point on bulk numerical work.

The program is structured as a small read–evaluate loop:

  1. Read a token (single character, number, or bracketed string).
  2. Dispatch to the operator implementation, which manipulates the main stack and possibly named-register stacks.
  3. Loop until end-of-input or q (quit).

Because the language is so small, the implementation is genuinely compact: the canonical GNU dc source is a few thousand lines of C, dominated by the arithmetic library rather than the interpreter itself.

Typical Usage

GNU dc is most often invoked from a shell pipeline as a one-shot RPN calculator:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Simple arithmetic, printed
echo "2 3 + p" | dc                 # 5

# Set scale and divide
echo "10 k 22 7 / p" | dc           # 3.1428571428

# Large exponent
echo "2 100 ^ p" | dc               # 1267650600228229401496703205376

# Hex to decimal
echo "16 i FF p" | dc               # 255

# Decimal to binary
echo "2 o 255 p" | dc               # 11111111

It is also a perfectly usable interactive REPL:

1
2
3
4
$ dc
[Hello, World!] p
Hello, World!
q

And, because of conditional execution and string registers, it can host genuine programs. The classic dc factorial is a two-line program:

[d 1 - d 1 <F * ] sF
5 lFx p

The macro F duplicates n, decrements, recurses while greater than 1, and multiplies on the way back up. Invoking it with 5 on the stack and printing yields 120.

Distribution and Versioning

GNU dc has no independent version number: it ships from the GNU bc source package, and its version is the version of the bc release it accompanied. The practically-relevant releases for users today are:

  • GNU bc 1.06 / 1.06.95 (approximately 2000–2006): the dc shipped with most early-2000s Linux distributions.
  • GNU bc 1.07.1 (reportedly September 2017): the dc adopted by Ubuntu 18.04 LTS, Debian Buster, and many other distributions for a long stretch of the late 2010s and early 2020s.
  • GNU bc 1.08 (reportedly released around late 2024): incorporates dc bug fixes and adds readline/libedit support to the interactive command line — long-requested by users.
  • GNU bc 1.08.x (2025): subsequent point releases reportedly available on rolling-release distributions and via Homebrew.

The long gap between 1.07.1 and 1.08 was a recurring source of community complaint and reportedly contributed to the rise of alternative bc/dc implementations such as Gavin Howard’s bc, which has been adopted as the default by FreeBSD and (according to upstream documentation) the Android Open Source Project. GNU dc remains, however, the implementation shipped on the great majority of Linux installations.

Licensing

GNU dc is licensed under the GNU General Public License, version 3 or later (older releases used GPL-2.0-or-later), in line with the bc source distribution it ships in. This is one practical reason that FreeBSD and Android prefer the BSD-licensed Gavin Howard rewrite for their base systems — but for GNU/Linux distributions, where GPL-licensed base utilities are the norm, GNU dc is the natural choice.

Current Status

GNU dc is actively maintained as part of the GNU bc project, hosted on GNU Savannah. Recent releases (reportedly bc 1.08 around 2024, followed by 1.08.x point releases) ended a long quiet period and indicate that the maintainers continue to ship meaningful improvements. For most users, GNU dc is invisible infrastructure — the program that runs when one types dc at a Linux shell prompt — but it remains the most widely-deployed dc implementation in the world.

Why GNU dc Matters

GNU dc matters for reasons that are easy to miss because the program itself is so small:

  1. It freed dc. Before GNU dc, the only widely-available dc was the AT&T Unix dc, which was not free software. Without a GPL-licensed replacement, early GNU/Linux distributions would have had to omit the utility or ship a non-free one.

  2. It made dc independent of bc. In the Bell Labs lineage, dc and bc were locked together: bc was a preprocessor that emitted dc postfix. GNU dc and GNU bc are siblings instead, each usable on its own — a design choice that has been preserved in every subsequent rewrite.

  3. It is the dc on Linux. A very large number of Linux installations — servers, containers, developer workstations, embedded systems — carry GNU dc as the default dc binary. When a shell pipeline computes a base conversion, when a quick RPN expression is evaluated at a terminal, or when an old script piping into dc is run on a modern distribution, the program doing the work is overwhelmingly GNU dc.

Like GNU bc, GNU dc is not a flashy piece of software. It is precisely the kind of small, correct, long-lived utility that the GNU Project was founded to produce — and, more than three decades after its first release, the version of dc that the majority of dc invocations on Earth actually run through.

Timeline

1971
The original dc appears in Version 1 AT&T Unix, written by Robert Morris and Lorinda Cherry at Bell Labs — predating the GNU implementation by two decades and establishing the RPN, stack-based, arbitrary-precision design that GNU dc later reimplements
1991
Philip A. Nelson releases the first version of GNU bc; the source distribution includes a companion GNU dc implementation, providing the GNU Project with a free-software replacement for the AT&T dc utility
1992
POSIX.2 (IEEE Std 1003.2-1992) standardizes bc but not dc; dc is consequently treated as a legacy utility outside POSIX, and GNU dc evolves without an external specification to track
2000
GNU bc 1.06 is released, bundling a long-stable GNU dc that ships in late-1990s and early-2000s Linux distributions including Red Hat and Debian
2003
OpenBSD 3.3 ships a clean-room rewrite of dc by Otto Moerbeek; the existence of an independent BSD implementation underscores GNU dc as the dominant — but no longer the only — modern dc
2017
GNU bc 1.07.1 released in September 2017, carrying the GNU dc shipped in Ubuntu 18.04 LTS, Debian Buster, and a generation of enterprise Linux distributions
2024
GNU bc 1.08 reportedly released around late 2024 after a multi-year quiet period, incorporating dc bug fixes and adding readline/libedit command-line editing in the interactive front-ends
2025
A subsequent GNU bc 1.08.x point release is reportedly available on rolling-release distributions; the bundled GNU dc reaches Arch Linux, Alpine, Homebrew, and similar package repositories

Notable Uses & Legacy

Linux Distributions

GNU dc is the default dc on Debian, Ubuntu, Fedora, openSUSE, Arch Linux, Alpine, and the great majority of GNU/Linux systems. It is installed as part of the 'bc' package (the bc and dc binaries ship together) and is available out of the box or via a one-line install on essentially every mainstream distribution.

Shell Pipelines and One-Liners

Because dc accepts expressions on standard input and prints with an explicit 'p' command, it is widely used in shell pipelines that need arbitrary-precision arithmetic with minimal startup cost. Common idioms include 'echo "2 64 ^ p" | dc' for very large powers and dc-based base conversions using the 'i' (input base) and 'o' (output base) commands.

Code Golf and RPN Demonstrations

GNU dc's tiny syntax and command-letter language make it a recurring choice on code-golf sites and in teaching reverse Polish notation. Macro support via string registers ('[ ... ] s_register' and 'l_register x') lets a few characters express genuine recursive programs, including the classic dc factorial and Fibonacci one-liners.

Homebrew on macOS

Homebrew packages GNU dc as part of the 'bc' formula, allowing macOS users to install the GNU dc binary alongside Apple's BSD-derived dc. Users who depend on GNU-specific dc commands — for example the extended register set or particular formatting behaviors — typically install the GNU version via Homebrew.

Educational Use

Operating-systems and programming-language courses occasionally use dc as a minimal example of a stack machine and as an introduction to reverse Polish notation. GNU dc is the implementation students most often encounter, because it is the one already installed on the Linux lab machines and on Windows Subsystem for Linux.

Language Influence

Influenced By

dc bc Reverse Polish Notation

Running Today

Run examples using the official Docker image:

docker pull alpine:latest

Example usage:

docker run --rm alpine sh -c 'apk add -q bc && echo "2 3 + p" | dc'
Last updated: