FUNDAMENTALS A Complete Guide for Beginners

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
```

Here, 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))`

Here, 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
```

`2 + 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, Moreover, the **expr** command can’t perform exponential operations. For example, the following command won’t work:

`expr 2 \*\* 3`

### 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"`

The 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`

In 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.

### 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. 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}'`

The 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`

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)"`

One 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))"`

In 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";'`

In 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 $?`

Here, **$?** 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 $?`

Here 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"
```

The 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
```

The 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))`

You 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"
```

The 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"
```

Here, 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"
```

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.

**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"
```

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.

**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"
```

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.

**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
```

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.

**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"
```

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.

**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**

**How to Calculate in Bash [3 Practical Examples]****How to Sum Up Numbers in Bash [Explained With Examples]****How to Divide Two Numbers in Bash [8 Easy Ways]****Division of Floating Point Numbers in Bash****How to Use “Mod” Operator in Bash [5 Basic Usage]****How to Format Number in Bash [6 Cases]****How to Generate Random Number in Bash [7 Easy Ways]****How to Convert Hexadecimal Number to Decimal in Bash****[Solved] “binary operator expected” Error in Bash****[Fixed] “integer expression expected” Error in Bash**

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

Can I copy from this article to my personal notes?