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 the 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 as follows:
$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 the 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 into 18.8 perfectly. This is just a shortcoming of calculations in the floating-point format used by computers.
Arbitrary Precision Modulus
PHP also has functions for calculating the Modulus for arbitrary precision numbers using the bcmod()
function from BC Math. Keep in mind that both the number have to be passed as strings for the function to work. Here are some examples:
<?php // Output: 0 echo bcmod('18', '6'); // Output: 20252374 echo bcmod('13209409782018', '34690436'); // Output: 458595967421388 echo bcmod('1809832098206280182084098320943890268', '643690782309520'); ?>
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 a 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 a 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 a user and asking them to only provide an 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 a Multiple of Some Other Number
In the above section, we used the modulo operator to inform users to only provide input values in certain multiples. 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 by 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 a 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 another 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 at the beginning of the post, in the 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 the 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 perform a specific task after every nth iteration. One practical use case that comes to mind is updating users about a long-running process. Let's say you are making changes to 1,000 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 other processes like resizing the images, adding watermarks, turning them grayscale, etc. (Check out my PHP GD image editing tutorials if you want to learn how to programmatically 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 seconds into the same duration expressed in hours, minutes, and seconds. Similarly, you could also convert a large number 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 3,600 and casting the value into an integer. This gives us the total number of hours since every hour has 3,600 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.
Calculating the GCD of Two Numbers
You can also use the Modulo operator to quickly calculate the greatest common divisor of two numbers. The trick is to keep calculating the modulo of the numbers and reassigning them until they divide completely.
<?php function get_gcd($a, $b) { while($a%$b != 0) { $temp = $a%$b; $a = $b; $b = $temp; } return $b; } // Output: 15 echo get_gcd(180, 525); // Output: 60 echo get_gcd(480, 1860); ?>
We keep calculating $a%$b
, if $b
does not completely divide $a
. After each calculation $b
is assigned to $a
and the modulo we calculated earlier is assigned to $b
. The value of $b
when the modulo becomes 0 is our GCD.
Calculating Modulus with Modular Exponentiation
Modular exponentation is used in many fields in computer science like cryptography. It relies on a property of modulus where:
(a ⋅ b) mod m = [(a mod m) ⋅ (b mod m)] mod m
We can create a function based on the above property to calcuate the remainder when dividing x y by m.
<?php function modular_expo($base, $exponent, $divisor) { if($divisor == 1) { return 0; } $me = 1; for($i = 0; $i < $exponent; $i++) { $me = ($me * $base) % $divisor; } return $me; } // Output: 155 echo modular_expo(44, 123, 497); ?>
Calculating the modulo by first evaluating the exponent 44 123 would have given us a 203 digit number. It would be much bigger if the exponent is over 1000. In such cases, using the above function will give us the modulo much more quickly.
The function simply returns 0 if the divisor is 1. Otherwise, it run a for loop for $exponent
number of iterations and calculate the modulus at each point. The end result is simply the remainder that we would have gotten by calculating the value of exponential expression and taking the modulo of the result.
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.
Learn PHP With a Free Online Course
If you want to learn PHP, check out our free online course on PHP fundamentals!
In this course, you'll learn the fundamentals of PHP programming. You'll start with the basics, learning how PHP works and writing simple PHP loops and functions. Then you'll build up to coding classes for simple object-oriented programming (OOP). Along the way, you'll learn all the most important skills for writing apps for the web: you'll get a chance to practice responding to GET and POST requests, parsing JSON, authenticating users, and using a MySQL database.
-
FREEPHPPHP Fundamentals
No comments:
Post a Comment