Bash Modulo (Division Remainder)
Last updated
Last updated
Many times we are only interested in what the remainder is. The mod operator finds use in generating random numbers within a specific range and formatting program output. It can even be used to generate prime numbers, check if a number is odd or even. Modulo turns up often in the majority of the numerical computations.
In this tutorial, we will learn about the modulus operations in bash.
Modulo is a binary operation that evaluates the remainder when one integer is divided by another. We often abbreviate the operator as mod and represent it by the symbol %. The remainder, if integers are involved, starts from 0 and every time increments by 1, until the number becomes just one less than the number we are dividing by. This sequence keeps repeating.
Here’s the syntax:
Given two integers x and y,
Where x is the dividend (numerator), y is the divisor (denominator), and r is the remainder.
We will then try to find the modulus of floating point numbers. We also will understand the precedence order. After this, we are going to put everything we have learned to practice and solve some real-world problems.
Bash provides us with a bunch of tools to carry out the modulus operation. Some of them are expr, let, double parentheses. We can also use some powerful tools like awk, bc and printf.
Example:
#!/bin/basha=12b=7echo
$a%$blet
result=$a%$b #Using letecho
$result
expr
$a % $b #Using expr
echo
$(($a%$b)) #Using $(())
echo
"$a%$b"
| bc
#Using bc
awk
"BEGIN {print $a%$b}"
#Using awk
printf
"%i\n"
$((a%b)) #Using printf
In this example we can see that, unlike other programming languages, we cannot perform the modulus operation directly. Bash will treat those variables as strings and print the result directly. As a result, we have used different command line tools to find the remainder when an integer is divided by another.
A floating point number is a positive or negative number with a decimal point. Most of the utilities used in the previous example cannot be used. However, we can make use of the powerful tools bash offers like bc and awk.
Example:
#!/bin/basha=100.0b=21
echo
"$a%$b"
| bc
#Using bc
awk
"BEGIN {print $a%$b}"
#Using awk
echo
"100.1%21"
| bc
#Using bc
awk
'BEGIN {x=100.1;y=21;print x%y}'
#Using awk
As we can see above, awk and bc are handy tools to perform the modulus. Another interesting thing that has come out is that the result of modulus may not always be an integer.
When evaluating expressions, Bash has specific rules for the modulo operator that determine its precedence. The modulo operator (%) always shares the same order of precedence as the multiplication (*) and division (/) operators. For overriding the precedence of other operators, we can surround the operation we want to evaluate first using parentheses
Example:
#!/bin/basha=2b=10c=6d=3
let
result="$a * $b % $c + $d"echo
$result
let
result="$a * $b % ($c + $d)"echo
$result
In the first case, we have both the multiplication and mod operators with the same order of precedence. Bash evaluates the expression from left to right. $a * $b is evaluated first and the result is the numerator for the modulus operation with $c. This newly generated number is then added to $d.
In the second case we are making use of parentheses to give higher priority to $c +$d. Hence, this expression is calculated first and then the usual evaluation will take place.
Now that we have understood in detail the modulo operator, we will put it to use to tackle real-world programming problems.
Example 1: To check if number is odd or even
#!/bin/bashecho
-n "Enter a number:"read
numif
[ `expr
$num % 2` == 0 ]then echo
"$num is even"else echo
"$num is odd"fi
A number if divided by 2, leaves the remainder 1 will be odd otherwise even. In this example we evaluate the expression using the modulus operator `expr $num % 2`. If it is to 0 then it is even otherwise it is odd.
Example 2: To convert hours from 24-hour format to 12-hour format
#!/bin/bashecho
-n "Enter the hour:"read
hourif
[ "$hour"
-gt 24 ] || [ "$hour"
-lt 0 ]then echo
Invalid hour entered. exit
1fiif
[ "$hour"
-eq
12 ]then echo
12pmelif
[ "$hour"
-eq
24 ]then echo
0amelif
[ "$hour"
-gt 12 ]then echo
"`expr $hour % 12` pm"else echo
"$hour am"fi
In this example we are only accepting integers between 0 to 24 and discarding any other entry. If the input is between 0 to 11 we print the input directly with am. If it is 12 or 24 we print the number and accordingly add am or pm. For the remaining numbers, we evaluate the expression using the modulus operator `expr $hour % 12` and append pm.
Example 3: To generate a random number within a specific range
#!/bin/bashecho
$(( $RANDOM % 50 )) #a random number between 0 to 50
This example is a simple way of generating a random number between 0 to 50. We are using the in-built $RANDOM variable to generate a random number. The generated random number is between 0 and 32767. However, we are setting the range of the number by dividing $RANDOM with 50 and getting the remainder using $RANDOM % 50.
Example 4: To run at specific intervals in a loop
#!/bin/bashfile=sample1.txtlineCount=`cat $file | wc -l`i=1while [[ $i -ne $lineCount ]]do if [ `expr $i % 3` == 0 ] then head -$i $file | tail +$i fi ((i++))done< $file
In this example we are displaying every third line of the file. We are using the modulus operator `expr $lineCount % 3` to get every third line.
Bash modulo operator is used to find the remainder.
The modulus operation can be performed on integers as well as floating point numbers.
The precedence of Bash modulus is similar to multiplication and division operators.
We can solve real world problems by making use of the modulus operator.