bc
An arbitrary-precision calculator language with C-like syntax, born at Bell Labs in 1975 and still a required POSIX utility on every Unix-like system today.
Created by Lorinda Cherry and Robert Morris (Bell Laboratories)
bc is an arbitrary-precision calculator language that has shipped with Unix systems since 1975. Conceived at Bell Laboratories by Lorinda Cherry and Robert Morris as a human-readable front end to the older dc desk calculator, bc proved so useful that it became a required POSIX utility — and remains one today. Despite its age, bc is still installed by default on macOS and virtually every Linux distribution, still included in FreeBSD, and still invoked daily by shell scripts that need to go beyond integers.
History & Origins
The dc Foundation
To understand bc, you first need to understand dc — the desk calculator that bc was built to complement. Robert Morris wrote dc at Bell Labs; by some accounts, it was one of the very first programs run on the Bell Labs PDP-11, and it was originally written in the B programming language before Unix was even written in C. dc uses reverse Polish notation (RPN): you push operands onto a stack and then apply operators, a style efficient for computation but unintuitive for expressing loops, conditionals, and general programs.
Lorinda Cherry and Robert Morris recognized that dc’s computation engine was powerful — arbitrary-precision decimal arithmetic, base conversion, a math library — but its stack-based, postfix syntax was a barrier to expressing structured programs. Their solution was bc.
Birth at Bell Labs (1975)
bc first appeared in Unix Version 6 in 1975. The design was elegant in its simplicity: bc was a preprocessor written in a single YACC source file. It accepted a C-like syntax — familiar to anyone who had used C, which was still a young language itself — and compiled it down to dc’s postfix notation, which dc then interpreted. The original paper, “BC - An Arbitrary Precision Desk-Calculator Language,” was authored by both Cherry and Morris and submitted from Bell Laboratories, Murray Hill, New Jersey.
The choice to model bc’s syntax on C was deliberate. As the original manual states, “those who are familiar with C will find few surprises in this language.” At Bell Labs in the mid-1970s, C was the lingua franca of systems programming, and making bc familiar to C programmers was a practical decision that guaranteed a ready audience.
Robert Morris and Lorinda Cherry
Robert Morris (July 25, 1932 – June 26, 2011) was a mathematician and cryptographer at Bell Labs from 1960 to 1986. His contributions to Unix include the math library, the crypt program, the Unix password encryption scheme, dc, and the co-authorship of bc. He later served as chief scientist at the NSA’s National Computer Security Center.
Lorinda Cherry was a Bell Labs researcher whose contributions to early Unix include co-creating bc and work on text processing tools. While secondary sources sometimes describe bc as “Cherry’s front end to Morris’s dc,” the original paper lists both Cherry and Morris as co-authors of bc.
Design Philosophy
Minimal, Familiar, and Precise
bc was designed as “a minimal language facility” — not a complete programming environment, but a focused tool for one task: arbitrary-precision decimal arithmetic, expressed in a syntax that C programmers could read without a manual. This minimalism is reflected throughout the language:
- One data type: all values are arbitrary-precision decimal numbers. There are no integers, floats, strings, or booleans in the POSIX specification.
- Small vocabulary: the POSIX standard defines a handful of control structures (
if,while,for,break), basic arithmetic operators, arrays, and user-defined functions. - Precision on demand: the global
scalevariable controls how many decimal places division and other operations produce. Settingscale=0gives integer-like truncation; settingscale=20gives twenty decimal places.
C Syntax for a Unix Audience
The decision to mirror C syntax was both practical and influential. By 1975, C was becoming the dominant systems programming language at Bell Labs and beyond. Giving bc a C-like surface syntax — curly braces, for loops, if statements, /* */ comments, and familiar operator precedence — meant that the barrier to using bc was essentially zero for anyone already writing C or shell scripts.
Key Features
Arbitrary-Precision Arithmetic
bc’s defining characteristic is that it performs arithmetic to arbitrary precision in decimal, not floating-point. The precision of a calculation is limited only by available memory, not by hardware floating-point registers. This makes bc correct for financial calculations, where binary floating-point introduces rounding errors that are unacceptable.
scale=50
pi = 4 * a(1) /* requires -l math library flag */
pi
This computes π to 50 decimal places using the arctangent identity, with no rounding error from floating-point representation.
Special Variables
bc provides three special global variables that control its behavior:
| Variable | Default | Purpose |
|---|---|---|
scale | 0 | Number of decimal places in results |
ibase | 10 | Input base (2–16) |
obase | 10 | Output base (2–16) |
The ibase and obase variables make bc a natural choice for base conversion:
ibase=16
FF /* output: 255 */
obase=2
255 /* output: 11111111 */
Built-in Math Library
The -l flag (load math library) activates six built-in mathematical functions and sets scale to 20:
| Function | Description |
|---|---|
s(x) | Sine of x (x in radians) |
c(x) | Cosine of x |
a(x) | Arctangent of x |
l(x) | Natural logarithm of x |
e(x) | Exponential (e^x) |
j(n,x) | Bessel function of integer order n |
User-Defined Functions and Arrays
bc supports user-defined functions with local variables and one-dimensional arrays:
define factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
factorial(20)
POSIX Standard vs. GNU Extensions
The POSIX specification defines a minimal core. GNU bc adds several practical extensions that are available on most Linux systems:
| Feature | POSIX bc | GNU bc |
|---|---|---|
| Variable names | Single lowercase letter | Multi-character |
if-else | if only | if-else |
print statement | No | Yes |
read() function | No | Yes |
continue in loops | No | Yes |
| Boolean operators | No | &&, ||, ! |
# line comments | No | Yes |
Architecture and Evolution
Original: A dc Preprocessor (1975)
The original bc was architecturally dependent on dc. A bc program was compiled by a YACC-generated parser into dc’s postfix notation and piped through dc for evaluation. This was a clever reuse of existing infrastructure: the hard work of arbitrary-precision arithmetic was already done by dc, and bc only needed to translate syntax.
The original manual noted a performance benchmark for its era: two 500-digit numbers could be multiplied to produce a 1,000-digit result in approximately ten seconds on the PDP-11 hardware of the time. This was a demonstration of capability rather than a promise of speed.
GNU bc: A Standalone Interpreter (1991)
Philip A. Nelson rewrote bc from scratch in 1991 as GNU bc, severing the architectural dependency on dc entirely. GNU bc is a standalone bytecode interpreter: it parses bc source, compiles it to an internal bytecode, and executes the bytecode directly. GNU bc also added the extensions listed above and is licensed under the GPL-3.0-or-later.
GNU bc became and remains the dominant bc implementation on Linux systems. Its version history reflects broad distribution adoption:
- 1.06.95: The long-stable version found in older enterprise Linux distributions
- 1.07.1 (April 10, 2017): Adopted in Ubuntu 18.04 LTS, Debian Buster, and many others
- 1.08 (December 31, 2024): Added readline/libedit command-line editing; dc bug fixes
- 1.08.2 (2025): Current stable release, available in Arch Linux, Alpine Edge, Homebrew, and other rolling-release distributions
OpenBSD bc: A Security-Focused Rewrite (2004)
OpenBSD 3.5 (released May 2004) included a complete rewrite of bc by Otto Moerbeek. Written in pure C with type-safe pointer usage and a completely rewritten lexer using lex(1), the OpenBSD bc adds several extensions (long variable names, # comments, boolean operators, print, continue, else, editline(3) integration, and -e flag for direct expression evaluation) while maintaining POSIX.1 compliance.
Gavin Howard’s bc: Modern Performance (FreeBSD, Android)
A newer implementation by Gavin Howard, written in ISO C99, offers improved performance for computationally intensive operations compared to GNU bc. It includes dc in the same binary (accessible via symbolic link) and a C library (bcl) exposing mathematical functions to C programs. This implementation was adopted as the default bc in FreeBSD 13 and 14 and is used in the Android Open Source Project; the implementations in Toybox and Busybox are also based on it. The project is now considered feature-complete, maintained for bug fixes only, and licensed under the BSD 2-clause license.
Running bc
Interactive Mode
Invoking bc without arguments opens an interactive REPL:
| |
Pipe Mode (Most Common)
The most common use is piping an expression through bc:
| |
In Docker (Alpine Linux)
There is no dedicated Docker Hub image for bc. The standard approach uses Alpine Linux, where bc is a single apk add away:
| |
Current Status
bc is active and required. It is listed as a required utility in POSIX Issue 8 (2024), ensuring its presence on any conforming Unix-like system. It ships by default on macOS (the system bc is available at /usr/bin/bc; Homebrew provides GNU bc 1.08.2 as an optional upgrade), and is installed by default or trivially available on Debian, Ubuntu, Fedora, Arch, Alpine, and all other major Linux distributions. FreeBSD and Android carry Gavin Howard’s bc as their system implementation.
GNU bc received active development attention in 2024-2025, including the long-requested addition of readline/libedit command-line editing support released in version 1.08 (December 2024).
Why bc Matters
bc occupies a small but irreplaceable niche in the Unix toolkit. It is not a general-purpose programming language — it lacks strings, file I/O, modules, and a standard library beyond the math functions. But for the task it was designed to perform — arbitrary-precision decimal arithmetic in a C-like syntax, scriptable from the shell — it remains unsurpassed in simplicity and availability.
Half a century after its creation, the same tool that Lorinda Cherry and Robert Morris shipped in Unix Version 6 continues to be invoked millions of times a day in shell scripts, CI/CD pipelines, system administration scripts, and interactive terminal sessions. It has been standardized, reimplemented four times by different authors, adopted in mobile operating systems, and remains a required POSIX utility. Few languages designed in 1975 can claim that record.
bc is also a reminder of the original Unix philosophy in its purest form: do one thing well, accept input on stdin, write output on stdout, and compose with other tools through pipes. A one-line bc invocation piped from echo and into a shell variable is one of the most natural expressions of that philosophy in the Unix toolkit.
Timeline
Notable Uses & Legacy
Unix Shell Scripting
bc is the canonical tool for floating-point and arbitrary-precision arithmetic in Bourne/POSIX shell scripts, where bash's built-in arithmetic is limited to integers. The idiom 'echo "scale=2; 5 * 7 / 3" | bc' appears throughout Unix scripting tutorials and production system scripts.
System Administration Scripts
System administrators use bc in shell scripts for disk space calculations, percentage threshold comparisons, and unit conversions that require decimal precision — tasks that cannot be accomplished with shell integer arithmetic alone.
Base Conversion Utilities
bc's ibase and obase variables make it the standard Unix tool for converting numbers between decimal, hexadecimal, octal, and binary in shell scripts and interactive sessions, without requiring Python or Perl.
Android Open Source Project
Google's Android Open Source Project uses Gavin Howard's bc implementation as the system bc, demonstrating that bc remains relevant even in embedded and mobile Linux environments.
FreeBSD Base System
FreeBSD 13 and 14 adopted Gavin Howard's bc as the system default, replacing GNU bc, as part of the project's ongoing transition to permissively-licensed base system components.
Language Influence
Influenced By
Running Today
Run examples using the official Docker image:
docker pull alpine:latestExample usage:
docker run --rm -i alpine sh -c 'apk add -q bc && echo "scale=10; 4*a(1)" | bc -l'