Performing Math Operations in Bash [12+ Commands Explained]

Mathematical or arithmetical calculations are essential for scheduling cron jobs, calculating the difference between the timestamps, and many other important tasks. There are different commands for doing math calculations in Bash. In this article, I will try to explain the commands for performing mathematical calculations with simple examples. I will also provide some practical examples where these commands can be useful.

Arithmetic Operators for Integer & Floating-Point Numbers

The Bash shell is primarily designed for performing arithmetic operations with whole numbers, both positive and negative, such as 1, -5, and 10. There are many arithmetic operators available in Bash such as addition, multiplication, subtraction, etc. These arithmetic operators facilitate arithmetic calculation. The below list contains basic arithmetic operators that users can use in Bash:

Operators Operation
+ Addition
Subtraction
* Multiplication
/ Division
% Modulus (remainder)
** Exponentiation

These operators can be used to perform arithmetic operations directly on integers, as well as on variables that contain integer values. However, when it comes to dealing with floating-point numbers like 3.14 or 2.5, users often need to rely on external utilities.

From this perspective, commands and utilities for arithmetic operations in Bash can be grouped into two categories- those that support floating point arithmetic and those that can’t.

Does Not Support Floating-Point Supports Floating-Point Arithmetic
declare -i bc
Arithmetic expansion dc
expr awk
let printf
test python2 or python3
Assignment Operator perl

It is obvious that the functions that support floating point can also perform integer arithmetic.

Commands for Arithmetic Operations in Bash

Now, I am going to discuss various commands and utilities for performing arithmetic operations. First, I will cover built-in commands such as declare and let. Then, I will delve into external utilities like awk, bc, perl, etc. Let’s continue.

1. “declare” Command

The declare command is used to set values to variables. The command option -i  is for declaring variables with integer values. One can perform mathematical calculations by defining a proper arithmetic expression by the following syntax:

declare -i var=expression

declare -i A=(2+3)**2
echo $A

declare command for arithmetic calculation in BashHere, the expression (2+3)**2 is evaluated first, resulting in 25. This calculated result later becomes the value of the variable A.

2. Arithmetic Expansion

Arithmetic expansion is the built-in way to perform mathematical calculations in Bash. One can calculate a valid expression by placing it within the double parentheses of $((…)). For instance,

echo $((10*2/5))

Arithmetic expansion for mathematical calculation in BashHere, arithmetic expansion calculates the result of multiplying 10 by 2 and then dividing the product by 5. The result of the calculation is 4 as you can see in the image.

3. “expr” Command

The expr command serves as an alternative to arithmetic expansion in Bash. It allows evaluating an expression when written appropriately following the word expr itself. The basic syntax is as follows:

expr expression

Let’s perform some calculations using the expr command:

expr 2 + 3
expr 2 \* 3

expr command for math in Bash2 + 3 performs the addition of 2 and 3.

2 \* 3 performs the multiplication of 2 and 3. Here, the multiplication sign * is placed after the escaped character backslash \ because the asterisk has a different meaning to Bash shell.

The space before and after the operator used in the expr command is important. If you remove those spaces, it returns back the expression itself. See the following image,Proper spacing in expr command for math in Bash Moreover, the expr command can’t perform exponential operations. For example, the following command won’t work:

expr 2 \*\* 3

Error in expr command while performing exponential in Bash

4. “let” Command

The let command allows users to perform mathematical calculations in a concise manner. The basic syntax is given below. Just replace the expression with the expression you want to evaluate.

let "var=expression"

See the following example of adding 2 and 3 using the let command:

let "result=2+3"

let command for math in BashThe result of addition 5 is stored in the result variable. Then the echo command displayed the result as you can see in the image above.

5. “bc” Command

The command bc stands for Basic Calculator. It is an easy-to-use command that allows users to perform arbitrary-precision arithmetic calculations. So it supports floating point arithmetic. Thus, the limitation of arithmetic expansion and the expr command can be overcome through this command tool.

To evaluate an expression using this command, you must first write the expression correctly and then pipe it to the command.

"expression" | bc

echo "10 * (3 + 2)" | bc

bc command for mathIn the above image, I want to evaluate the expression “10 * (3 + 2)”.  It represents the multiplication of 10 by the sum of 3 and 2. The echo command is used to write the expression and pipe (|) is used to redirect the standard output to the bc command. The bc command evaluates the expression and shows the result 50.

6. “dc” Command

The dc command stands for desk calculator. It is a Reverse Polish Notation(RPN) calculator. That means the numbers of a calculation are given first then the operator is defined. The basic syntax is similar to the bc command. Such as,

"expression" | dc

Look at the following command that evaluates the expression “10 * (3 + 2)”:

echo "3 2 + 10 * p" | dc

Here, the relationship between 3 and 2 is addition. The addition sign is placed after the numbers are given. After the addition operator adds the top two elements of the stack (3 and 2), 10 is pushed onto the stack.

Then the multiplication operator * multiplies 5 and 10 and pushes the result (50) back onto the stack.dc command for math in Bash

7. “awk” Command

The awk command is a text-processing utility that also supports mathematical calculations. It can handle floating point arithmetic. One can write the expression to be evaluated within the BEGIN block or use the printf command. Let’s evaluate the expression 10 * (3 + 2) using the awk:

echo "10 3 2" | awk '{printf "%.0f\n", $1 ^ ($2 + $3)}'

Here,the echo command is used to pass the numbers involved in the calculation. Then these numbers are piped to the awk command. The awk command reads the numbers using the $1, $2, and $3 respectively. Within the printf block the 10 * (3 + 2) is defined using the $1 ^ ($2 + $3). Format specifier "%.0f\n" indicates that no decimal places should be shown, effectively rounding the result to an integer.awk command for math in Bash The command outputs the result by rounding to an integer, that is 50.

Now, look at the use of the BEGIN block to evaluate the addition of 3 and 2:

awk 'BEGIN {print 3 + 2}'

awk command with BEGIN block for performing arithmetic calculationThe output of the expression ‘5’ is displayed.

8. “printf” Command

The printf command with arithmetic expansion can perform arithmetic calculations up to the desired precision. The general syntax is as follows:

printf "%.<precision>f" $((10**<precision>*expression))e-<precision>

To perform a certain calculation replace the expression with the expression you want to evaluate and set your desired precision value in place of precision in the above syntax. Look at the following example:

echo printf "%.4f" $((10**4*(10*4/20)))e-4

printf command to perform arbitrary precision arithmetic

OUTPUT ANALYSIS

Here, $((10**4*(10*4/20))) performs arithmetic expansion. First, 10 raised to the power of 4, which is 10000. Then 10 is multiplied by 4, yielding 40. Finally, 40 is divided by 2, resulting in 2. 10000 multiplied by 2 gives 20000.

In $((10**2*5/2))e-4, the result of arithmetic expansion is multiplied by e-4 which represents multiplying the preceding value by 10 to the power of -4. In this case, it means dividing the preceding value by 10000. So, 20000e-4 is equivalent to 2.0000.

The printf "%.4f\n" statement specifies a format for printing. %.4f specifies that the number should be formatted as a floating point with four decimal places.

9. “python3” Command

One can use Python functionality in Bash using the python2 and python3 commands. In the following command, I use python3 to perform the simple multiplication of 5 and 3:

python3 -c "a = 5; b = 3; print(a * b)"

python command for math in BashOne can even import Python libraries and use their built-in functions for math calculations. math is one of the popular libraries in Python for mathematical tasks. Let’s import math and use its sqrt function to calculate the square root of a number:

python -c "import math; print(math.sqrt(25))"

Python math library for arithmetic calculation in BashIn the above example, I imported the math library to calculate the square root of 25.

10. “perl” Command

Like using Python, one can execute perl code from the terminal. The perl command with the -e option can perform arithmetic calculations. Along with basic math operations, one can use built-in math functions too. For example,

perl -e 'print sqrt(25) + 3**2, "\n";'

perl code in Bash for arithmetic calculationIn the above example, I used the print statement to output the result in the terminal. In the calculation part, sqrt(25) calculated the square root of 25, which is 5. Then added it with 3 raised to the power of 2, resulting in 14.

11. “test” Command

The test command in Bash can evaluate conditional expressions and result in either 0 or 1 for true or false conditions respectively. For instance,

test 5 -gt 2; echo $?

test command for evaluating arithmetic condition in BashHere, $? checks the exit status of the previous command. The exit status of the previous command is 0 as 5 greater than 2 is a true condition.

Alternatively, one can use square brackets instead of the test command to evaluate a mathematical condition. For that use the following command:

[ 5 -gt 10 ]; echo $?

Double square bracket for evaluating math condition in BashHere the exit status is 1 because 5 greater than 10 is a false statement.

Note: Make sure you put a space after and before the starting and the closing square brackets respectively. Otherwise, there will be a syntax error and exit status will be different and not the proper representation of the evaluation of the condition.

12. Assignment Operator

Assignment operators are used to assign values to variables. One can use the assignment operators to perform basic arithmetic such as addition, multiplication, division, etc. Let’s perform the addition operation using the “+=” assignment operator:

x=5
(( x += 15 ))
echo "After Increment, x=$x"

Increment operator for addition in BashThe initial value of x is 5. After that, x is increased by 15. So the final value of x is 20.

13. Built-in Math Functions in Bash

Apart from the commands for basic mathematical calculation, there are few built-in commands for specific math tasks- like the factor command. This command is used for the prime factorization of an integer number. It can even factor multiple numbers at a time. See the below example:

factor 30
factor 30 60

factor command for prime factorization of numbers in BashThe first command gives the prime factors of 30. The second command gives the factors of 30 and 60 at a time. You can even provide more than two arguments in the factor command and get the prime factorization of all the given numbers.

Mathematical Calculation in Different Arithmetic Bases

Bash arithmetic is not limited to decimal-based numbers. One can easily change the base and perform necessary arithmetic calculations. To define the base of a number use the following syntax:

base#number

The default value of base is 10 which indicates decimal number format. The base can be any integer from 2 to 64. Where 2 denotes binary number format. Now, let’s calculate 2 plus 3 in binary number format:

echo $((2#10 + 2#11))

Binary base of numbers in BashYou can see that the command adds 10 and 11 which are binary representations of 2 and 3. The result of addition is shown in decimal number format.

In the same manner, octal (base 8) numbers take the prefix 0 instead of 8# to define the base. Let’s try to sum up 8 and 16 in octal:

echo $((010+020))

One can even change the base of the result. Look at the commands below to display the result of the addition in octal format:

result=$((010+020))
printf "In Octal Format: %o\n" "$result"

Octal base for mathematical calculation in BashThe image shows that the summation of 10 and 20 in octal is 24 in decimal and 30 in octal.

Finally, the hexadecimal numbers (base 16) can be defined using the prefix 0x. For instance, 11 in hexadecimal is 0xB. Now, I am going to sum up 11 and 2 in hex:

echo $((0x2+0xB))
result=$((0x2+0xB))
printf "Result in hexadecimal base: %X\n" "$result"

Hexadecimal base for arithmetic calculation in BashHere, the format specifier %X\n in printf command defines that the result should be printed in hexadecimal format. So the addition of 11 and 2 is 13 in decimal and D in hex.

Practical Examples of Mathematical Operations in Bash

The best way to perform a mathematical operation in Bash depends on the nature of the calculation. Here are some practical bash scripts that heavily depend on mathematical calculation:

A. Finding the Maximum of Three Numbers

To find the maximum of three numbers one needs to evaluate multiple conditional statements. Let’s create a Bash script that can find the highest number among three numbers using the elif conditional statements:

#!/bin/bash

# Function to find the maximum of three numbers
find_max() {
if [ "$1" -ge "$2" ] && [ "$1" -ge "$3" ]; then
echo "$1"
elif [ "$2" -ge "$1" ] && [ "$2" -ge "$3" ]; then
echo "$2"
else
echo "$3"
fi
}

# Call the function and store the result in the variable max
max=$(find_max $1 $2 $3)
# Print the result
echo "The maximum number is: $max"
EXPLANATION

The script defines a function called find_max that takes three positional parameters. [ "$1" -ge "$2" ] && [ "$1" -ge "$3" ] checks if the value of $1 is greater than both $2 and $3. In the elif block, it compares the second positional argument with the other two. If the if block and the elif block don’t hold true by default the third positional parameter is the maximum number among the three numbers.

Finding maximum of three numbers in BashHere, the three given numbers are 10, 14 and 12. Among the given numbers 14 is the highest as you can see in the image.

B. How to Find the Factorial of a Number in Bash

The factorial of a non-negative integer number is denoted by the product of all positive integers less than and equal to that integer number. One can easily calculate the factorial of a number in Bash by writing a few lines of code. For example,

#!/bin/bash

factorial () {
if (($1 > 1))
then
echo $(( $( factorial $(($1 - 1)) ) * $1 ))
else
echo 1
return
fi
}

# Call the function and store the result
fac=$(factorial $1)
# Print the result
echo "The factorial of $1 is: $fac"
EXPLANATION

The script defines a function called factorial. Within this function, an if block checks whether the first positional parameter  (input argument) is greater than one. If this condition is true, the function recursively calls itself with the argument decremented by 1 and multiplies the result by the argument. This process continues until the argument becomes 1, effectively calculating the factorial by multiplying the original argument down to 1.

On the other hand, if the first positional argument is already 1, the function echoes 1 as the factorial.

Factorial of a number in BashAfter I run the program with the argument 5, it returns 120 as the factorial of 5.

C. Calculating Difference Between Two Dates in Bash

Users often try to calculate the difference between two dates. It involves converting the dates into Unix epochs and then performing the subtraction to find the difference. Let me show the process in a script:

#!/bin/bash

# Function to calculate the difference in days between two dates
diff_in_days() {
local start_date="$1"
local end_date="$2"

# Convert dates to Unix timestamps
local start_timestamp=$(date -d "$start_date" +%s)
local end_timestamp=$(date -d "$end_date" +%s)

# Calculate the difference in seconds and convert to days
local diff_in_seconds=$((end_timestamp - start_timestamp))
local diff_in_days=$((diff_in_seconds / 86400))
echo "$diff_in_days"
}

# Prompt the user for the start date
read -p "Enter the start date (YYYY-MM-DD): " start_date
# Prompt the user for the end date
read -p "Enter the end date (YYYY-MM-DD): " end_date

# Calculate and print the difference in days
result=$(diff_in_days "$start_date" "$end_date")
echo "The difference in days between $start_date and $end_date is: $result days"
EXPLANATION

The script calculates the difference in days between two dates provided by the user. It defines a function called diff_in_days that takes two dates as arguments. Then it converts the dates to Unix timestamps using the date command with the %s format specifier. After conversion, it calculates the difference between dates in seconds and then converts this difference to days.

Finding difference between two dates in BashI run the program and try to find the difference in days between the dates “2022-05-20” and “2023-07-25”. It shows that the difference between these two dates is 431 days.

D. Bits to Bytes Conversion in Bash

One can convert bits to bytes by dividing the number of bits by 8, as there are 8 bits in a byte. Here is how you can do this in Bash:

#!/bin/bash

# Function to convert bits to bytes
bits_to_bytes() {
bits=$1
bytes=$(echo "scale=2; $bits / 8" | bc)
echo "$bits bits is $bytes bytes"
}

# Call the function
bits_to_bytes $1
EXPLANATION

The Bash script defines a function named bits_to_bytes that takes a number of bits as an argument. It uses the bc command to perform the conversion from bits to bytes by dividing the number of bits by 8. The scale=2 specifies that the result should have two decimal places. The script then echoes the original number of bits along with the calculated equivalent in bytes.

Bit to Byte conversion in BashHere, I’m trying to figure out the bytes equivalent to 1024 bits. The program shows that 128.00 bytes is equal to 1024 bits.

E. How to Find LCM and GCD of Two Numbers in Bash

To find the Least Common Multiple (LCM) and Greatest Common Divisor (GCD) of two numbers in Bash, use a combination of loops and arithmetic expansion. For instance,

#!/bin/bash

# Function to calculate the Greatest Common Divisor (GCD) using Euclidean algorithm
gcd() {
local a=$1
local b=$2
while [ "$b" -ne 0 ]; do
local temp="$b"
b=$((a % b))
a="$temp"
done
echo "$a"
}

# Function to calculate the Least Common Multiple (LCM)
lcm() {
local a=$1
local b=$2
local gcd_result=$(gcd "$a" "$b")
local product=$((a * b))
echo "$((product / gcd_result))"
}

# Calculate GCD
result_gcd=$(gcd "$1" "$2")
# Calculate LCM
result_lcm=$(lcm "$1" "$2")

# Print the results
echo "The GCD of $1 and $2 is: $result_gcd"
echo "The LCM of $1 and $2 is: $result_lcm"
EXPLANATION

This script defines two functions gcd and lcm. The gcd function can find the Greatest Common Divisor of two numbers. The function takes two parameters, a and b, representing the numbers for which the GCD needs to be determined. Within the function, a while loop continues as long as b is not equal to 0. In each iteration, it swaps the values of a and b, and updates b to the remainder of the division of the original a by the original b. This process continues until b becomes 0, at which point the GCD is found.

The lcm function calculates the Least Common Multiple (LCM) of two numbers by dividing the product of the two numbers by their GCD. The GCD is obtained by calling the gcd function with the same parameters.

LCM and GCD of two numbers in BashHere I provided two numbers 12 and 30 to find their LCM and GCD. The program successfully showed that the GCD of the numbers is 6 and the LCM of the numbers is 60.

Conclusion

In conclusion, mathematical operations are required for many applications. There are many commands and techniques for doing math in Bash. I hope after reading this article you can perform your necessary math calculations in Bash shell. Let me know if you face any issues while performing the arithmetic calculation.

People Also Ask

Why “value too great for base” error occurs in arithmetic calculation in Bash?

The “value too great for base” error in Bash occurs when someone tries to perform arithmetic calculations using a base that is not appropriate for the numbers involved. For instance, in the expression echo $((2#1010 + 2#6)), the error arises because the number 6 in base-2 (2#6) exceeds the binary representation, causing an arithmetic overflow. In this case, the base specified cannot accommodate the numeric value provided, leading to the error.

To resolve this, it’s important to ensure that the base used in arithmetic calculations can represent the numbers involved without exceeding its capacity.

How to solve the “syntax error: invalid arithmetic operator” in Bash?

“syntax error: invalid arithmetic operator” typically occurs when there is an issue in the arithmetic expression or the capability of the command used for evaluating the expression. To solve the error use a command based on the nature of the expression. Let’s say you are calculating with floating point numbers but using arithmetic expansion to do that. This raises the error. To evaluate such expressions choose a command that can handle floating point arithmetic.

How to solve the “non-integer argument” error in Bash?

To solve the “non-integer argument” issue, provide an integer number instead of a floating point number. This issue often occurs when someone tries to evaluate an expression involving a floating point number with the expr command.

How can I generate random numbers for mathematical calculation in Bash?

To generate random numbers in Bash use the RANDOM environment variable. One can also set the limits to get random numbers within a defined range. For example, to generate a random integer within the range of 1 to 100, use the following code:

echo $((RANDOM % 100 + 1)


Related Articles


<< Go Back to Arithmetic Operators in Bash | Bash Operator | Bash Scripting Tutorial

5/5 - (1 vote)
Md Zahidul Islam Laku

Hey, I'm Zahidul Islam Laku currently working as a Linux Content Developer Executive at SOFTEKO. I completed my graduation from Bangladesh University of Engineering and Technology (BUET). I write articles on a variety of tech topics including Linux. Learning and writing on Linux is nothing but fun as it gives me more power on my machine. What can be more efficient than interacting with the Operating System without Graphical User Interface! Read Full Bio

Leave a Comment