Skip to main content

Command documentation sourced from the linux-command project This comprehensive command reference is part of the linux-command documentation project.

bc - Arbitrary precision calculator language

The bc command is an arbitrary-precision calculator language that provides interactive calculation capabilities as well as support for complex mathematical operations. It offers both a simple calculator interface and a full programming language with variables, functions, loops, and conditional statements. BC supports arbitrary precision arithmetic, making it ideal for calculations that require high accuracy beyond standard floating-point limitations. It includes support for scientific functions, base conversions, and can be used interactively or in shell scripts for automated calculations.

Basic Syntax

bc [OPTIONS] [FILE...]

Common Options

Standard Options

  • -h, --help - Display help information
  • -v, --version - Show version information
  • -i, --interactive - Force interactive mode
  • -l, --mathlib - Load the standard math library
  • -q, --quiet - Don't print the normal GNU bc welcome
  • -s, --standard - Process strictly the POSIX bc language
  • -w, --warn - Warn about extensions to POSIX bc

Execution Options

  • -f, --file=FILE - Read commands from FILE instead of standard input
  • -e, --expression=EXPR - Evaluate the expression and exit

Usage Examples

Interactive Calculator

Basic Arithmetic Operations

# Start bc in interactive mode
bc

# Once in bc:
> 2 + 3
5
> 10 - 4
6
> 7 * 8
56
> 15 / 3
5
> 17 % 5
2

# Set precision for decimal calculations
> scale=10
> 22 / 7
3.1428571428

Advanced Mathematical Operations

# Power operations
> 2^10
1024
> 3^4
81

# Square root
> sqrt(16)
4
> sqrt(2)
1.4142135623

# Last result (.)
> 10 * 5
50
> . + 25
75

Using Math Library

Trigonometric Functions

# Load math library for advanced functions
bc -l

# Set precision
> scale=10

# Sine, cosine, tangent
> s(3.14159/6)
.4999999999
> c(3.14159/4)
.7071067811
> a(1)
.7853981634

# Natural logarithm and exponential
> l(10)
2.3025850929
> e(1)
2.7182818284

# Logarithm base 10
> l(100)/l(10)
2

Command Line Calculations

Direct Expression Evaluation

# Simple calculations
echo "2 + 3 * 4" | bc
# Output: 14

# Division with precision
echo "scale=6; 22/7" | bc
# Output: 3.142857

# Power calculations
echo "2^16" | bc
# Output: 65536

# Complex expressions
echo "scale=4; (15 + 25) * 3.5 / 2" | bc
# Output: 70.0000

Multiple Calculations

# Using here document
bc << EOF
scale=6
pi = 22/7
radius = 5
area = pi * radius^2
print "Area of circle with radius ", radius, " = ", area, "\n"
EOF

# From file
echo "
scale=4
a = 10
b = 15
c = sqrt(a^2 + b^2)
print 'Hypotenuse: ', c, '\n'
" | bc -l

Base Conversions

Binary, Octal, and Hexadecimal

# Convert decimal to binary
echo "obase=2; 42" | bc
# Output: 101010

# Convert decimal to octal
echo "obase=8; 64" | bc
# Output: 100

# Convert decimal to hexadecimal
echo "obase=16; 255" | bc
# Output: FF

# Convert binary to decimal
echo "obase=10; ibase=2; 101010" | bc
# Output: 42

# Convert hexadecimal to decimal
echo "obase=10; ibase=16; FF" | bc
# Output: 255

Advanced Base Operations

# Convert between arbitrary bases (2-16)
echo "obase=3; ibase=8; 75" | bc
# Output: 10220

# Base conversion with variables
echo "
ibase=16
hex_val = FF
obase=2
hex_val
" | bc
# Output: 11111111

Shell Script Integration

Basic Script Usage

#!/bin/bash
# Simple calculator script

# Get user input
read -p "Enter first number: " num1
read -p "Enter second number: " num2

# Perform calculations
sum=$(echo "$num1 + $num2" | bc)
product=$(echo "$num1 * $num2" | bc)
quotient=$(echo "scale=4; $num1 / $num2" | bc)

echo "Sum: $sum"
echo "Product: $product"
echo "Quotient: $quotient"

Advanced Mathematical Functions

#!/bin/bash
# Scientific calculator functions

# Function to calculate factorial
factorial() {
echo "define f(x) {
if (x <= 1) return 1
return x * f(x-1)
}
f($1)" | bc -l
}

# Function to calculate compound interest
compound_interest() {
local principal=$1
local rate=$2
local time=$3

echo "scale=8; $principal * (1 + $rate/100)^$time" | bc -l
}

# Function to calculate loan payment
loan_payment() {
local principal=$1
local annual_rate=$2
local years=$3

local monthly_rate=$(echo "scale=8; $annual_rate/1200" | bc -l)
local months=$(echo "$years * 12" | bc)

echo "scale=2; $principal * $monthly_rate / (1 - (1 + $monthly_rate)^(-$months))" | bc -l
}

Practical Examples

System Administration

Disk Usage Calculations

#!/bin/bash
# Disk usage analyzer

# Get disk usage statistics
total_kb=$(df / | tail -1 | awk '{print $2}')
used_kb=$(df / | tail -1 | awk '{print $3}')
available_kb=$(df / | tail -1 | awk '{print $4}')

# Convert to GB
total_gb=$(echo "scale=2; $total_kb/1024/1024" | bc)
used_gb=$(echo "scale=2; $used_kb/1024/1024" | bc)
available_gb=$(echo "scale=2; $available_kb/1024/1024" | bc)

# Calculate percentage
usage_percent=$(echo "scale=1; $used_kb*100/$total_kb" | bc)

echo "Disk Usage Analysis:"
echo "Total: ${total_gb}GB"
echo "Used: ${used_gb}GB"
echo "Available: ${available_gb}GB"
echo "Usage: ${usage_percent}%"

Memory Usage Monitoring

#!/bin/bash
# Memory usage calculator

# Get memory info
total_mem=$(free -b | grep Mem | awk '{print $2}')
used_mem=$(free -b | grep Mem | awk '{print $3}')
available_mem=$(free -b | grep Mem | awk '{print $7}')

# Convert to MB
total_mb=$(echo "scale=2; $total_mem/1024/1024" | bc)
used_mb=$(echo "scale=2; $used_mem/1024/1024" | bc)
available_mb=$(echo "scale=2; $available_mem/1024/1024" | bc)

# Usage percentage
usage_percent=$(echo "scale=1; $used_mem*100/$total_mem" | bc)

echo "Memory Usage:"
echo "Total: ${total_mb}MB"
echo "Used: ${used_mb}MB (${usage_percent}%)"
echo "Available: ${available_mb}MB"

Development Workflow

Unit Test Calculator

#!/bin/bash
# Mathematical testing calculator

# Test function for verifying calculations
test_calculation() {
local expression=$1
local expected=$2
local result=$(echo "$expression" | bc -l)

if [ "$(echo "$result == $expected" | bc -l)" -eq 1 ]; then
echo "✓ PASS: $expression = $result"
else
echo "✗ FAIL: $expression = $result (expected $expected)"
fi
}

# Run tests
echo "Running mathematical tests..."
test_calculation "2 + 2" "4"
test_calculation "10 * 5" "50"
test_calculation "scale=6; 1/3" ".333333"
test_calculation "2^8" "256"

Build Script with Progress Calculation

#!/bin/bash
# Build progress calculator

total_files=100
processed_files=0

# Simulate build process
for i in {1..100}; do
processed_files=$((processed_files + 1))
progress_percent=$(echo "scale=1; $processed_files * 100 / $total_files" | bc)
remaining=$(echo "$total_files - $processed_files" | bc)

printf "\rProgress: %s%% | Processed: %d | Remaining: %d" \
"$progress_percent" "$processed_files" "$remaining"

sleep 0.05
done

echo -e "\nBuild completed!"

Financial Calculations

Investment Calculator

#!/bin/bash
# Investment return calculator

calculate_investment() {
local principal=$1
local annual_rate=$2
local years=$3

echo "define compound_interest(p, r, t) {
auto i, result
result = p
for (i = 1; i <= t; i++) {
result = result * (1 + r/100)
}
return result
}
scale = 2
compound_interest($principal, $annual_rate, $years)" | bc -l
}

# Example usage
principal=10000
rate=7
years=10

final_amount=$(calculate_investment $principal $rate $years)
profit=$(echo "scale=2; $final_amount - $principal" | bc -l)

echo "Investment Analysis:"
echo "Principal: \$$(printf "%.2f" $principal)"
echo "Annual Rate: ${rate}%"
echo "Years: $years"
echo "Final Amount: \$$(printf "%.2f" $final_amount)"
echo "Total Profit: \$$(printf "%.2f" $profit)"

Loan Amortization Calculator

#!/bin/bash
# Loan amortization schedule calculator

calculate_amortization() {
local principal=$1
local annual_rate=$2
local years=$3

# Calculate monthly payment
local monthly_rate=$(echo "scale=8; $annual_rate/1200" | bc -l)
local months=$(echo "$years * 12" | bc)

local payment=$(echo "scale=2; $principal * $monthly_rate / (1 - (1 + $monthly_rate)^(-$months))" | bc -l)

echo "Monthly Payment: \$$payment"
echo ""
echo "Amortization Schedule:"
printf "%-8s %-12s %-12s %-12s %-15s\n" "Month" "Payment" "Principal" "Interest" "Balance"
echo "------------------------------------------------------------"

local balance=$principal
for month in $(seq 1 $months); do
local interest_payment=$(echo "scale=2; $balance * $monthly_rate" | bc -l)
local principal_payment=$(echo "scale=2; $payment - $interest_payment" | bc -l)
balance=$(echo "scale=2; $balance - $principal_payment" | bc -l)

printf "%-8d \$%-11s \$%-11s \$%-11s \$%-14s\n" \
"$month" "$payment" "$principal_payment" "$interest_payment" "$balance"
done
}

# Example usage
calculate_amortization 200000 4.5 30

Advanced Usage

Programming Features

Loops and Conditionals

bc << EOF
/* Generate multiplication table */
define multiplication_table(n) {
auto i, j
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
print i, " * ", j, " = ", i * j, "\n"
}
}
}

/* Calculate factorial recursively */
define factorial(n) {
if (n <= 1) return 1
return n * factorial(n - 1)
}

/* Check if number is prime */
define is_prime(n) {
auto i
if (n <= 1) return 0
if (n <= 3) return 1
if (n % 2 == 0) return 0
for (i = 3; i * i <= n; i += 2) {
if (n % i == 0) return 0
}
return 1
}

/* Test functions */
scale = 0
print "Factorial of 6: ", factorial(6), "\n"
print "Is 17 prime? ", is_prime(17), "\n"
print "Is 15 prime? ", is_prime(15), "\n"

multiplication_table(5)
EOF

Custom Functions Library

cat > mathlib.bc << 'EOF'
/* Extended mathematical functions */

/* Fibonacci sequence */
define fibonacci(n) {
if (n <= 1) return n
return fibonacci(n-1) + fibonacci(n-2)
}

/* Greatest common divisor */
define gcd(a, b) {
while (b != 0) {
auto temp
temp = b
b = a % b
a = temp
}
return a
}

/* Least common multiple */
define lcm(a, b) {
return a * b / gcd(a, b)
}

/* Power with decimal exponent */
define power(base, exp) {
auto result, i
result = 1
for (i = 1; i <= exp; i++) {
result = result * base
}
return result
}

/* Average of numbers */
define average(a, b) {
return (a + b) / 2
}

/* Quadratic formula solver */
define quadratic_solution(a, b, c, type) {
auto discriminant, sqrt_discriminant
discriminant = b * b - 4 * a * c
if (discriminant < 0) return "No real solutions"

sqrt_discriminant = sqrt(discriminant)
if (type == 1) {
return (-b + sqrt_discriminant) / (2 * a)
} else {
return (-b - sqrt_discriminant) / (2 * a)
}
}
EOF

# Use the custom library
bc -l mathlib.bc << EOF
scale = 6
print "Fibonacci of 10: ", fibonacci(10), "\n"
print "GCD of 48 and 18: ", gcd(48, 18), "\n"
print "LCM of 12 and 15: ", lcm(12, 15), "\n"
print "First root of x^2 - 5x + 6 = 0: ", quadratic_solution(1, -5, 6, 1), "\n"
print "Second root of x^2 - 5x + 6 = 0: ", quadratic_solution(1, -5, 6, 2), "\n"
EOF

Scientific Calculations

Physics Formulas

#!/bin/bash
# Physics calculator using bc

# Constants (SI units)
GRAVITY=9.81
SPEED_OF_LIGHT=299792458
PLANCK_CONSTANT=0.000000000000000000000000000000000662607015

# Function to calculate kinetic energy
kinetic_energy() {
local mass=$1
local velocity=$2

echo "scale=4; $mass * $velocity^2 / 2" | bc -l
}

# Function to calculate gravitational potential energy
potential_energy() {
local mass=$1
local height=$2

echo "scale=4; $mass * $GRAVITY * $height" | bc -l
}

# Function to calculate Einstein's mass-energy equivalence
mass_energy() {
local mass=$1

echo "scale=4; $mass * $SPEED_OF_LIGHT^2" | bc -l
}

# Example calculations
echo "Physics Calculations:"
echo "===================="
echo "Kinetic Energy (10kg, 5m/s): $(kinetic_energy 10 5) J"
echo "Potential Energy (10kg, 10m): $(potential_energy 10 10) J"
echo "Mass-Energy (1kg): $(mass_energy 1) J"

Engineering Calculations

#!/bin/bash
# Engineering calculations

# Function to calculate stress
calculate_stress() {
local force=$1
local area=$2

echo "scale=2; $force / $area" | bc -l
}

# Function to calculate strain
calculate_strain() {
local change_length=$1
local original_length=$2

echo "scale=6; $change_length / $original_length" | bc -l
}

# Function to calculate Young's modulus
youngs_modulus() {
local stress=$1
local strain=$2

echo "scale=2; $stress / $strain" | bc -l
}

# Function to calculate moment of inertia (rectangular beam)
moment_of_inertia() {
local width=$1
local height=$2

echo "scale=4; $width * $height^3 / 12" | bc -l
}

# Beam deflection calculation
beam_deflection() {
local force=$1
local length=$2
local young_modulus=$3
local moment_inertia=$4

echo "scale=6; $force * $length^3 / (3 * $young_modulus * $moment_inertia)" | bc -l
}

# Example usage
echo "Engineering Calculations:"
echo "======================="
force=1000 # N
area=0.01 # m²
stress=$(calculate_stress $force $area)
echo "Stress: $stress Pa"

width=0.1 # m
height=0.2 # m
moment=$(moment_of_inertia $width $height)
echo "Moment of Inertia: $moment m⁴"

Data Analysis

Statistical Calculations

#!/bin/bash
# Statistical analysis with bc

# Function to calculate mean
calculate_mean() {
local numbers=("$@")
local sum=0
local count=${#numbers[@]}

for num in "${numbers[@]}"; do
sum=$(echo "$sum + $num" | bc -l)
done

echo "scale=4; $sum / $count" | bc -l
}

# Function to calculate variance
calculate_variance() {
local numbers=("$@")
local mean=$(calculate_mean "${numbers[@]}")
local sum_squared_diff=0
local count=${#numbers[@]}

for num in "${numbers[@]}"; do
local diff=$(echo "$num - $mean" | bc -l)
local squared_diff=$(echo "$diff * $diff" | bc -l)
sum_squared_diff=$(echo "$sum_squared_diff + $squared_diff" | bc -l)
done

echo "scale=4; $sum_squared_diff / $count" | bc -l
}

# Function to calculate standard deviation
calculate_std_dev() {
local numbers=("$@")
local variance=$(calculate_variance "${numbers[@]}")

echo "scale=4; sqrt($variance)" | bc -l
}

# Example dataset
data=(10 15 12 18 14 20 16 13 11 17)

mean=$(calculate_mean "${data[@]}")
variance=$(calculate_variance "${data[@]}")
std_dev=$(calculate_std_dev "${data[@]}")

echo "Statistical Analysis:"
echo "===================="
echo "Data: ${data[@]}"
echo "Mean: $mean"
echo "Variance: $variance"
echo "Standard Deviation: $std_dev"

Linear Regression

#!/bin/bash
# Simple linear regression

# Function to calculate linear regression coefficients
linear_regression() {
local x_values=("$@")
local n=$((${#x_values[@]} / 2))

# Extract x and y values
local x_arr=()
local y_arr=()

for ((i=0; i<n; i++)); do
x_arr[i]=${x_values[i]}
y_arr[i]=${x_values[i+n]}
done

# Calculate sums
local sum_x=0
local sum_y=0
local sum_xy=0
local sum_x2=0

for ((i=0; i<n; i++)); do
sum_x=$(echo "$sum_x + ${x_arr[i]}" | bc -l)
sum_y=$(echo "$sum_y + ${y_arr[i]}" | bc -l)
sum_xy=$(echo "$sum_xy + ${x_arr[i]} * ${y_arr[i]}" | bc -l)
sum_x2=$(echo "$sum_x2 + ${x_arr[i]} * ${x_arr[i]}" | bc -l)
done

# Calculate coefficients
local slope=$(echo "scale=4; ($n * $sum_xy - $sum_x * $sum_y) / ($n * $sum_x2 - $sum_x * $sum_x)" | bc -l)
local intercept=$(echo "scale=4; ($sum_y - $slope * $sum_x) / $n" | bc -l)

echo "Slope: $slope"
echo "Intercept: $intercept"
echo "Equation: y = ${slope}x + ${intercept}"
}

# Example usage
echo "Linear Regression Analysis:"
echo "========================="
data=(1 2 3 4 5 2 4 6 8 10) # x values: 1,2,3,4,5; y values: 2,4,6,8,10
linear_regression "${data[@]}"

Integration and Automation

Pipeline Integration

Processing Large Datasets

#!/bin/bash
# Process CSV data with bc calculations

# Function to process a CSV file
process_csv() {
local input_file=$1
local output_file=$2

echo "Processing $input_file..."

# Skip header and calculate column operations
tail -n +2 "$input_file" | while IFS=',' read -r col1 col2 col3; do
# Perform calculations
sum=$(echo "$col1 + $col2 + $col3" | bc -l)
average=$(echo "scale=2; $sum / 3" | bc -l)

# Write to output
echo "$col1,$col2,$col3,$sum,$average" >> "$output_file"
done

echo "Results saved to $output_file"
}

# Create sample data
cat > sample_data.csv << EOF
Value1,Value2,Value3
10,20,30
15,25,35
8,12,16
22,18,25
EOF

# Process the data
process_csv sample_data.csv results.csv
echo "Results:"
cat results.csv

Real-time Calculations

#!/bin/bash
# Real-time calculator with file monitoring

monitor_and_calculate() {
local input_file=$1
local output_file=$2

echo "Monitoring $input_file for new calculations..."

# Monitor file for changes
inotifywait -m "$input_file" | while read path action file; do
if [ "$action" = "MODIFY" ]; then
echo "File modified, processing new calculations..."

# Read the last line and calculate
local last_line=$(tail -n 1 "$input_file")
local result=$(echo "$last_line" | bc -l)

# Save result with timestamp
echo "$(date '+%Y-%m-%d %H:%M:%S') - Expression: $last_line = $result" >> "$output_file"
echo "Calculated: $last_line = $result"
fi
done
}

# Create input file
touch calculations.txt
touch results.log

# Start monitoring (run in background)
monitor_and_calculate calculations.txt results.log &
MONITOR_PID=$!

echo "Enter calculations (one per line) into calculations.txt"
echo "Results will be saved to results.log"
echo "Press Ctrl+C to stop"

# Wait for user to stop
trap "kill $MONITOR_PID; exit" INT
wait

Web Integration

Calculator Web Service

#!/bin/bash
# Simple web-based calculator service

calculator_service() {
local port=$1

echo "Starting calculator service on port $port..."

while true; do
# Listen for HTTP request
echo -e "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n" > response.tmp

# Process calculation
if [[ $REQUEST_URI =~ expr=(.+) ]]; then
local expression="${BASH_REMATCH[1]//%20/ }"
local result=$(echo "$expression" | bc -l 2>/dev/null || echo "Error")
echo "Expression: $expression = $result" >> response.tmp
else
echo "Usage: http://localhost:$port/?expr=2+2" >> response.tmp
fi

# Send response
cat response.tmp

sleep 0.1
done | nc -l -p $port

rm -f response.tmp
}

# Note: This is a simplified example
# In production, use proper web server
echo "Calculator Web Service"
echo "===================="
echo "To test, run: curl 'http://localhost:8080/?expr=2+2'"
echo "Starting service..."
# calculator_service 8080

Troubleshooting

Common Issues

Precision Problems

# Issue: Floating point precision errors
# Solution: Use appropriate scale settings

echo "Problem: 1/3 with default precision"
echo "1/3" | bc
# Output: 1

echo "Solution: Set scale for decimal precision"
echo "scale=6; 1/3" | bc
# Output: .333333

# High precision calculations
echo "scale=20; 22/7" | bc
# Output: 3.14285714285714285714

Syntax Errors

# Common syntax errors and fixes

# Error: Missing semicolon
echo "scale=4 22/7" | bc
# Fix: Add semicolon
echo "scale=4; 22/7" | bc

# Error: Invalid base conversion
echo "obase=17; 255" | bc
# Fix: Use valid base (2-16)
echo "obase=16; 255" | bc

# Error: Division by zero
# Solution: Add error checking
divide_safely() {
local dividend=$1
local divisor=$2

if [ "$divisor" = "0" ]; then
echo "Error: Division by zero"
return 1
fi

echo "scale=4; $dividend / $divisor" | bc -l
}

Performance Issues

# Issue: Slow calculations with large numbers
# Solution: Optimize calculations

# Use appropriate precision
echo "scale=2; large_calculation" | bc # Faster than scale=100

# Break down complex calculations
complex_calc() {
local step1=$(echo "scale=10; $1 * $2" | bc -l)
local step2=$(echo "scale=10; $step1 / $3" | bc -l)
echo "scale=4; $step2 + $4" | bc -l
}

# Use built-in functions when possible
echo "sqrt(16)" | bc -l # Faster than echo "16^0.5" | bc -l

Memory Issues

# Issue: Memory exhaustion with recursive functions
# Solution: Use iterative approaches

# Inefficient recursive factorial
echo "define fact_rec(n) {
if (n <= 1) return 1
return n * fact_rec(n-1)
}
fact_rec(100)" | bc -l

# Efficient iterative factorial
echo "define fact_iter(n) {
auto result, i
result = 1
for (i = 2; i <= n; i++) {
result = result * i
}
return result
}
fact_iter(100)" | bc -l
  • dc - Desk calculator (RPN-based)
  • expr - Evaluate expressions
  • awk - Pattern scanning and processing language
  • python - Python programming language
  • node - Node.js JavaScript runtime
  • perl - Perl programming language
  • printf - Format and print data
  • let - Shell arithmetic evaluation

Best Practices

  1. Set appropriate precision with scale for decimal calculations
  2. Use math library (-l flag) for scientific functions
  3. Validate input before performing calculations
  4. Use proper error handling for division by zero and invalid expressions
  5. Store results in variables for complex multi-step calculations
  6. Use appropriate base settings (ibase, obase) for number conversions
  7. Optimize recursive functions to prevent stack overflow
  8. Test edge cases like zero, negative numbers, and large values
  9. Use shell functions to wrap common bc operations
  10. Document custom functions and libraries for reuse

Performance Tips

  1. Use minimal precision required for your calculations
  2. Prefer built-in functions over custom implementations
  3. Use iterative algorithms instead of recursive when possible
  4. Break complex calculations into smaller steps
  5. Cache frequently used values in variables
  6. Use appropriate number bases for conversion operations
  7. Avoid unnecessary temporary variables in performance-critical code
  8. Use shell arithmetic for simple integer operations when possible
  9. Batch multiple calculations in a single bc session
  10. Profile complex functions to identify bottlenecks

The bc command is a versatile and powerful tool for arbitrary-precision calculations, offering both a simple calculator interface and a full programming language. Its ability to handle precise decimal calculations, support for scientific functions, and integration capabilities make it an essential tool for mathematical computations, financial calculations, scientific analysis, and automated processing tasks. Whether used interactively or in scripts, bc provides reliable mathematical computation capabilities that exceed standard shell arithmetic limitations.