In this lesson, you will learn why standard shell arithmetic fails with decimals and how to use the bc (Basic Calculator) utility to maintain precision in your scripts.
The Limitation of Shell Arithmetic
In Bash, standard arithmetic using the $(( )) syntax is strictly limited to integer math. If you try to calculate 5 / 2, Bash will return 2 instead of 2.5, truncating the decimal entirely. While this is fine for counting files or loops, it causes catastrophic errors when your scripts need to handle percentages, ratios, or financial data.
Introducing bc for Precision
To handle floating-point numbers, we leverage bc, a language designed for arbitrary-precision arithmetic. Since bc is an external command, we bridge it with our script using a "here-string" or a pipe.
To perform a calculation with decimal precision, you must define the scale variable. The scale determines how many digits appear after the decimal point.
Example: Accurate Division
Imagine you are calculating a success rate for a backup job:
# Calculate 5 divided by 2 with 2 decimal places
result=$(echo "scale=2; 5 / 2" | bc)
echo "The result is: $result"
In this snippet:
scale=2tellsbcto keep two decimal places.- The pipe
|sends the expression tobc. - The result
2.50is captured into the variableresult.
Handling Variables
When using variables inside bc, ensure they are quoted correctly. You can pass shell variables into the calculation effortlessly:
num1=10
num2=3
# Calculate 10 / 3 with 4 decimal places
result=$(echo "scale=4; $num1 / $num2" | bc)
echo "Calculation: $num1 / $num2 = $result"
Because bc handles the math outside of the shell's integer-only constraints, you can perform complex logic reliably. Always remember that bc does not round by default—it truncates—so if you need to perform high-stakes financial rounding, ensure your logic accounts for the scale carefully.
Key Takeaway: Since Bash natively ignores decimals, always pipe your expressions into bc and define a scale to guarantee the precision your script requires.