bc Command in Linux: Command-Line Calculator

By 

•

Published on

•

10 min read

bc calculator showing decimal division with scale set to four places

When a shell script needs to divide two numbers, compute a percentage, or work with decimals, the shell itself is not much help. Bash arithmetic only handles integers, which means echo $((10 / 3)) gives you 3 instead of 3.33. The bc command fills that gap. It is an arbitrary-precision calculator that reads expressions from files or standard input and prints the result.

This guide walks through the most common ways to use bc, from quick one-liners to full expressions inside scripts.

bc Syntax

The bc command takes the following form:

txt
bc [OPTIONS] [FILE...]

Without arguments, bc starts an interactive session that reads expressions line by line until you type quit or press Ctrl+D on an empty line. More commonly, you pipe an expression into it and print the result:

Terminal
echo "2 + 3" | bc
output
5

Here, bc reads 2 + 3 from the pipe and prints 5. You can use the same pattern for more involved calculations.

If bc is not installed, add it with your package manager. On Ubuntu, Debian, and derivatives, run:

Terminal
sudo apt update
sudo apt install bc

On Fedora, RHEL, and derivatives, run:

Terminal
sudo dnf install bc

Basic Arithmetic

bc supports the standard operators you would expect from a calculator: +, -, *, /, % for remainder, and ^ for exponentiation. Use an integer exponent with ^, such as 2 ^ 10. Pipe an expression into bc and you get the answer:

Terminal
echo "15 * 4 - 10" | bc
output
50

Multiplication runs before subtraction, so bc subtracts 10 from 60. Parentheses override that default order:

Terminal
echo "(15 + 5) * 3" | bc
output
60

With parentheses, bc adds 15 and 5 first, then multiplies the sum by 3.

One thing that often surprises new users is that bc truncates division results to integers by default, the same way shell arithmetic does:

Terminal
echo "10 / 3" | bc
output
3

The fractional part is discarded, leaving 3. To keep decimal places in division, you need to set scale.

Working with Decimals Using scale

For division, the scale variable sets the number of digits to keep after the decimal point. It must be a non-negative integer and defaults to 0. You can set it at the start of the expression, separated by a semicolon:

Terminal
echo "scale=4; 10 / 3" | bc
output
3.3333

This keeps four decimal places in the quotient. scale is not a general output format: addition and subtraction keep the decimal places of their operands, and multiplication also depends on the operands. For example, scale=2; 1.234 + 5.678 still returns 6.912.

Another common pattern is to pass -l (short for “math library”), which sets scale to 20 and loads the standard math functions:

Terminal
echo "10 / 3" | bc -l
output
3.33333333333333333333

The quotient now has 20 decimal places. For a shorter result, set scale yourself:

Terminal
echo "scale=2; 100 / 7" | bc
output
14.28

Notice that bc truncates rather than rounds. The value starts with 14.2857, and with scale=2 you get 14.28, not 14.29. To round a value for display, calculate with extra decimal places and format the result with the printf command :

Terminal
result=$(echo "scale=6; 100 / 7" | bc)
LC_ALL=C printf '%.2f\n' "$result"
output
14.29

The %.2f format prints two decimal places, and LC_ALL=C makes printf use a dot as the decimal separator. Unlike bc, printf uses fixed-precision floating-point arithmetic, so keep calculations that need arbitrary precision inside bc.

Math Functions

With the -l flag, bc exposes a small set of math functions that are useful for more than pocket-calculator arithmetic:

  • s(x) - sine of x (in radians)
  • c(x) - cosine of x (in radians)
  • a(x) - arctangent of x
  • l(x) - natural logarithm of x
  • e(x) - exponential function, e raised to the x
  • j(n, x) - Bessel function of integer order n at x

You can use a(1) * 4 to approximate pi:

Terminal
echo "4 * a(1)" | bc -l
output
3.14159265358979323844

The output has 20 decimal places, but intermediate calculations can affect the last digits. If you need a particular number of accurate decimal places, calculate at a higher scale first.

The sqrt() function is built in and works without -l. In this example, -l supplies the higher scale for the square root of 2:

Terminal
echo "sqrt(2)" | bc -l
output
1.41421356237309504880

Without -l or an explicit scale, sqrt(2) returns 1. The GNU bc manual documents the built-in functions and the math library separately.

Using bc in Shell Scripts

The real payoff comes when you use bc in a script. Capture the result with command substitution and assign it to a variable:

Terminal
total=150
tax_rate=0.08
tax=$(echo "scale=2; $total * $tax_rate" | bc)
echo "Tax: $tax"
output
Tax: 12.00

The shell expands $total and $tax_rate before passing the expression to bc, then stores 12.00 in tax.

In Bash, a here-string (<<<) lets you pass the expression without a pipe. It also supports variable expansion, but it is not part of POSIX sh:

Terminal
result=$(bc -l <<< "5.5 * 2.3")
echo "$result"
output
12.65

The multiplication produces 12.65, which command substitution stores in result.

A common task inside scripts is comparing decimal numbers, which Bash cannot do directly. GNU bc prints 1 for true and 0 for false, so you can test the output:

Terminal
if [ "$(echo "3.14 > 2.71" | bc)" -eq 1 ]; then
    echo "pi is greater than e"
fi
output
pi is greater than e

Since 3.14 is greater than 2.71, bc prints 1 and the shell runs the echo command. This pattern is useful when a script needs to check a load average or a disk-usage percentage against a decimal threshold. Standalone comparisons are a GNU bc extension and are rejected in strict POSIX mode (bc -s).

Converting Between Number Bases

bc can convert numbers between bases using the ibase (input base) and obase (output base) variables. To convert decimal to binary, set obase=2:

Terminal
echo "obase=2; 42" | bc
output
101010

The decimal value 42 is printed as binary 101010.

To convert hexadecimal to decimal, set ibase=16. Hex digits must be uppercase:

Terminal
echo "ibase=16; FF" | bc
output
255

Hexadecimal FF becomes decimal 255. Lowercase letters are variable names in bc, so ff is not a hexadecimal number.

When setting both bases, put obase before ibase. After ibase changes, multi-digit constants are interpreted in the new input base. For example, obase=10 after ibase=16 sets the output base to decimal 16, not 10. Single-digit constants keep their value regardless of ibase.

To convert hexadecimal directly to binary, use:

Terminal
echo "obase=2; ibase=16; FF" | bc
output
11111111

The output 11111111 is the binary representation of hexadecimal FF.

Reading Expressions from a File

If you have a long calculation or want to reuse a set of formulas, save them to a file named calc.bc:

calc.bctxt
scale=4
price=49.99
quantity=12
discount=0.15
subtotal = price * quantity
subtotal - (subtotal * discount)

Read the file through standard input so bc exits when it reaches the end:

Terminal
bc < calc.bc
output
509.8980

The calculation applies a 15 percent discount to 12 items priced at 49.99, giving 509.8980. bc evaluates each line in order. Assignments store values without printing them; the final expression produces the output.

You can also pass the filename as an argument with bc calc.bc. After reading the file, bc continues reading standard input, so it waits for more expressions when you run it from a terminal. Type quit or press Ctrl+D on an empty line to exit.

Defining Functions

When the built-in functions are not enough, you can write your own with the define keyword. A function takes its parameters in parentheses and sends a value back with return:

txt
define name(parameters) {
    auto local_variables
    statements
    return (expression)
}

Parameters and the variables listed after auto are local to the function. Any other variable you assign inside the body is global and keeps its value after the function returns.

A short function fits on one line, together with the call:

Terminal
echo 'define sq(x) { return (x * x) }; sq(12)' | bc
output
144

bc stores the sq function first, then evaluates sq(12) and prints the result.

Longer functions are easier to keep in a file. The following funcs.bc defines pow(), which handles decimal exponents (^ ignores the fractional part of the exponent and prints a warning), and fact(), which calculates factorials:

funcs.bctxt
define pow(x, y) {
    auto s, r
    s = scale
    scale = s + 10
    r = e(y * l(x))
    scale = s
    return (r / 1)
}

define fact(n) {
    auto i, r
    r = 1
    for (i = 2; i <= n; i++) r *= i
    return (r)
}

pow() adds 10 extra digits of scale while it calculates, which keeps the small errors from e() and l() out of the digits you see. It then restores the original scale, and dividing by 1 trims the result to that precision. fact() multiplies the numbers from 2 to n in a for loop.

Because pow() calls e() and l() from the math library, load the file together with -l. When you pass a file and pipe an expression at the same time, bc reads the file first, then evaluates the expression from standard input and exits:

Terminal
echo "pow(2, 0.5)" | bc -l funcs.bc
output
1.41421356237309504880

Raising 2 to the power of 0.5 gives the same result as sqrt(2). The natural logarithm is defined only for positive numbers, so use pow() with a positive base. With a zero or negative base, bc exits with Fatal error: Out of memory for malloc.

Factorials show what arbitrary precision means in practice:

Terminal
echo "fact(25)" | bc -l funcs.bc
output
15511210043330985984000000

The result has 26 digits. Bash arithmetic wraps around after 9223372036854775807, the largest 64-bit signed integer, while bc keeps every digit.

Quick Reference

TaskCommand
Simple calculationecho "2 + 3" | bc
Decimal divisionecho "scale=4; 10 / 3" | bc
With math libraryecho "10 / 3" | bc -l
Square rootecho "sqrt(16)" | bc
Powerecho "2 ^ 10" | bc
Integer remainderecho "scale=0; 17 % 5" | bc
Decimal to binaryecho "obase=2; 42" | bc
Hex to decimalecho "ibase=16; FF" | bc
Compare floatsecho "3.14 > 2.71" | bc
Read from file and exitbc < calc.bc
Load your own functionsecho "fact(25)" | bc -l funcs.bc

Troubleshooting

Division returns 0 instead of a decimal
Set scale at the start of the expression, or call bc with -l. Without either, bc truncates division results to integers.

Hexadecimal input returns 0
Use uppercase digits and set ibase=16 before the number. In GNU bc, ff is an uninitialized variable with a value of 0; FF is the hexadecimal number that converts to 255.

The remainder changes when you use -l
The % operator depends on scale. For an integer remainder, set scale=0 before the expression: echo "scale=0; 17 % 5" | bc -l returns 2.

bc: command not found
Install the bc package with sudo apt install bc on Ubuntu or Debian, or sudo dnf install bc on Fedora or RHEL. Minimal systems and containers may not include it.

Syntax errors in decimal input
Use a dot as the decimal separator (3.14), and omit thousands separators (1000, not 1,000). bc does not accept commas inside numeric literals.

Conclusion

Set scale explicitly when division precision matters, and keep extra decimal places until you format the result. For calculations that only need integers, see our guide to Bash arithmetic .

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page