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
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:
| Command | Meaning |
|---|---|
<digits> | Push a number onto the stack |
+ - * / % | Pop two operands, push the result |
^ | Exponentiation |
v | Square root (pop one, push its root) |
p | Print the top of stack (without popping) |
n | Print and pop |
f | Print the entire stack |
c | Clear the stack |
d | Duplicate the top of stack |
r | Swap (reverse) the top two values |
k | Set the precision (scale) from the top of stack |
i o | Set the input and output radix |
s_X, l_X | Store to / load from named register X |
[ ... ] | Push a string |
x | Execute 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_XandL_Xcommands 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.-eand-fcommand-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:
- Read a token (single character, number, or bracketed string).
- Dispatch to the operator implementation, which manipulates the main stack and possibly named-register stacks.
- 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:
| |
It is also a perfectly usable interactive REPL:
| |
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:
It freed dc. Before GNU dc, the only widely-available
dcwas the AT&T Unixdc, 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.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.
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
dcbinary. When a shell pipeline computes a base conversion, when a quick RPN expression is evaluated at a terminal, or when an old script piping intodcis 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
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
Running Today
Run examples using the official Docker image:
docker pull alpine:latestExample usage:
docker run --rm alpine sh -c 'apk add -q bc && echo "2 3 + p" | dc'