PHP has a total of eight arithmetic operators. The most common are addition (+
), subtraction (-
), multiplication (*
) and division (/
). A slightly lesser-known, though still very important operator is modulo (%
). In this tutorial, we'll focus on the modulo operator. We will discuss what it does and some of its practical uses.
What Does the Modulo Operator Do?
If you have two variables $a
and $b
, calculating $a % $b
—usually pronounced "a modulo b" or "a mod b"—will give you the remainder after dividing $a
by $b
. Modulo is an integer operator, so it converts both the operands to integers before calculating the remainder. So basically modulo does integer division and then gives back whatever is left from the dividend.
The sign of the value returned by a modulo operation is determined by the sign of the dividend. In division, the result after dividing two negative numbers will be a positive number. However, that's not the case with the modulo operator. The sign of divisor has no effect on the final value.
Here are a couple of examples:
<?php echo 1089 % 37; // Output: 16 echo 1089 % -37; // Output: 16 echo -1089 % 37; // Output: -16 echo -1089 % -37; // Output: -16 echo -55.4 % -4.2; // Output: -3 echo -55.9 % -4.8; // Output: -3 echo -55 % -4; // Output: -3 ?>
Floating Point Modulo
If you want to calculate the remainder when two floating point numbers are divided by each other, you will have to use the fmod($dividend, $divisor)
function. It returns the floating point remainder after the division. The remainder value will have the same sign as the dividend and its magnitude will be less than the divisor. The three numbers are related by following relation:
$dividend = i*$divisor + $remainder
Here, the value i
will always be an integer.
You should remember that floating point arithmetic is not always accurate due to limitations of the binary or decimal representation of fractions. For example, 1/3 cannot be accurately represented in decimal form. You can keep writing 0.33333.... but at some point you would have to stop. You will get closer to the original value with each additional 3 in the decimal representation but the value will still not be exactly 1/3.
This kind of inaccuracy causes problems with the fmod()
function: the results are not entirely reliable.
Here are some examples of the fmod()
function:
<?php echo fmod(18.8, 2); // Output: 0.8 echo fmod(18.8, 0.2); // Output: 0.2 ?>
The second value isn't accurate because 0.2 divides 18.8 perfectly. This is just a shortcoming of calculations in the floating point format used by computers.
Uses of the Modulo Operator
In this tutorial, we will restrict ourselves to integer modulo because it is much more common and has a lot of applications.
Checking if a Number is Multiple of Some Other Number
The result of the modulo operator is zero if the first number is perfectly divisible by the second number. This could be used to check if one number is multiple of the other in a given number pair. Probably the most common use of this property of the modulo operator is in checking if a number is even or odd. Here is an example:
<?php $colors = ['violet', 'indigo', 'blue', 'green', 'yellow', 'orange', 'red']; $color_count = count($colors); if($color_count % 2 == 0) { echo 'We have created some color pairs for you.'; } else { echo 'Please specify one more or one less color to make pairing possible.'; } ?>
In the above example, you could be getting the list of colors from some user and ask them to only provide even number of colors.
The example below uses a similar reasoning to create groups with 5 students each. In real life, you will have to use extra code to group the students but the basic idea of checking if the total students are multiples of 5 does not change.
<?php $total_students = 25; if($total_students % 5 == 0) { echo 'Each group of five students has been given an assignment.'; } else { echo 'Sorry, it is impossible to create groups of five students right now. Please get more students.'; } ?>
Changing Numbers to be Multiple of Some Other Number
In the above section, we used the modulo operator to inform users to only provide input values in certain multiple. If that is not possible, we can also force the input to be even as well as a multiple of 5 or some other number.
The modulo operator provides the whole number left after dividing the first number with the second number. This means that subtracting the remainder from the first number will make it a multiple of the second number. For example, 28 can be changed to be multiple of 5 by taking the modulo 28 % 5. In this case, the modulo will be 3. We can now subtract 3 from the original number to make it a multiple of 5. The following line will force any positive number x
to be a multiple of some other positive number y
by subtracting an appropriate value from it.
x = x - (x % y)
In our previous example with 28 students, we could just leave 3 students out and group other students together.
<?php $total_students = 28; if($total_students % 5 == 0) { echo 'Each group of five students has been given an assignment.'; } else { $removed_students = $total_students % 5; $total_students -= $removed_students; echo 'We have created groups of five students by removing the last '.$removed_students.' students from the list.'; } ?>
Put a Limit on the Input
As I mentioned in the beginning of the post, in case of positive numbers the modulo operator will return a number between 0 and N - 1, where N is the divisor. This means that you can put a cap on any input and do some operations repetitively and sequentially. Here is an example:
<?php $colors = ['violet', 'indigo', 'blue', 'green', 'yellow']; $color_count = count($colors); $total_images = 180; $background_color = ''; for($i = 0; $i < $total_images; $i++) { $background_color = $colors[$i % $color_count]; echo "Setting image background color to $background_color."; } ?>
In the above example, we have just five colors but a total of 180 images. This means that we will have to keep looping through the same five colors and assign them to all our images. The modulo operator fits this need perfectly. It will restrict the value of $i % $color_count
between 0 and (5 - 1) or 4 inclusive. In other words, we will be able to pick all colors of our array sequentially very easily.
Do Some Task Every Nth Time in a Loop
When traversing a loop, we can check the value of a variable incremented with each pass through the loop and do some specific task after every nth iteration. One practical use case that comes to mind is updating users about some long-running process. Lets say you are making changes to 1000 different images using PHP. If the changes are significant, this process will take a while to update all images.
In such cases, the users will have no way of knowing if the program is just stuck or actually making any progress. What you could do is report the progress to users after editing every 10th image.
<?php $total_images = 1000; for($i = 1; $i <= $total_images; $i++) { update_images($image_resource); if($i % 10 == 0) { $percent = $i*100/$total_images; echo 'Already processed '.$percent.'% images.'; } } ?>
The update_images()
function in the above example is completely made up but you could replace it with some other processes like resizing the images, adding watermark, turning them gray scale etc. (Check out my PHP GD image editing tutorials if you want to learn how to programatically edit images in PHP yourself.)
Converting Between Different Units of Measurement
The modulo operator can also be used to convert between different units of measurement. For example, you could use it to change a time duration expressed in number of seconds into the same duration expressed in hours, minutes and seconds. Similarly, you could also convert a large of centimeters into kilometers, meters and centimeters. Here is an example:
<?php $total_seconds = 32987; $hours = (int)($total_seconds / 3600); $minutes = (int)(($total_seconds - 3600 * $hours )/60); $seconds = $total_seconds % 60; echo 'Hours:'.$hours.' Minutes:'.$minutes.' Seconds:'.$seconds.''; ?>
We begin by simply dividing the total number of seconds by 3600 and casting the value into an integer. This gives us the total number of hours since every hour has 3600 seconds. In the next step, we subtract 3600 * $hours
from the original number of seconds. This gets rid of all the seconds that we have converted to hours. Dividing by 60 now will give us the total number of minutes. Finally, we use the modulo operator to get the number of seconds.
Final Thoughts
As you saw in this tutorial, the modulo operator, though easy to use, has a lot of applications. We began this tutorial by looking at the modulo of both positive and negative numbers as well as floats. After that we covered some common scenarios where we would use modulo.
If you have any questions related to this tutorial, please let me know in the comments. Do you have any other uses of modulo in mind? Please share them with fellow readers by posting them below.
No comments:
Post a Comment