php 一共有八个算术运算符。最常见的是加法 ( +)、减法 ( -)、乘法 ( *) 和除法 ( /)。一个鲜为人知但仍然非常重要的运算符是模 ( %)。在本教程中,我们将重点介绍模运算符。我们将讨论它的作用以及它的一些实际用途。
模运算符有什么作用?
如果您有两个变量 $a 和 $b,计算 $a % $b(通常发音为“a modulo b”或“a mod b”)将得到除以 后的余 $a 数 $b。Modulo 是一个整数运算符,因此它在计算余数之前将两个操作数都转换为整数。所以,基本上,模进行整数除法,然后返回被除数剩下的任何东西。
模运算返回的值的符号由被除数的符号决定。在除法中,两个负数相除后的结果将是一个正数。但是,模运算符并非如此。除数的符号对最终值没有影响。
这里有几个例子:
<?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 ?>
浮点模数
如果要计算两个浮点数相除时的余数,则必须使用该 fmod($dividend, $divisor) 函数。它返回除法后的浮点余数。余数将与被除数具有相同的符号,并且其大小将小于除数。这三个数字的关系如下:
$dividend = i*$divisor + $remainder
在这里,该值 i 将始终为整数。
您应该记住,由于分数的二进制或十进制表示的限制,浮点运算并不总是准确的。例如,1/3 不能以十进制形式准确表示。你可以继续写 0.33333.... 但在某些时候你必须停下来。十进制表示中每增加一个 3,您将更接近原始值,但该值仍不会恰好是 1/3。
这种不准确性会导致 fmod() 函数出现问题:结果并不完全可靠。
以下是该 fmod() 函数的一些示例:
<?php echo fmod(18.8, 2); // Output: 0.8 echo fmod(18.8, 0.2); // Output: 0.2 ?>
第二个值不准确,因为 0.2 完美地划分为 18.8。这只是计算机使用的浮点格式计算的一个缺点。
任意精度模数
bcmod() PHP 还具有使用BC Math中的函数计算任意精度数的模数的 函数。请记住,两个数字都必须作为字符串传递,函数才能工作。这里有些例子:
<?php // Output: 0 echo bcmod('18', '6'); // Output: 20252374 echo bcmod('13209409782018', '34690436'); // Output: 458595967421388 echo bcmod('1809832098206280182084098320943890268', '643690782309520'); ?>
模运算符的使用
在本教程中,我们将使用整数模数,因为它更常见并且有很多应用程序。
检查一个数字是否是其他数字的倍数
如果第一个数完全可以被第二个数整除,则模运算符的结果为零。这可用于检查一个数字是否是给定数字对中另一个数字的倍数。模运算符的这个属性最常见的用途可能是检查一个数字是偶数还是奇数。这是一个例子:
<?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.'; } ?>
在上面的示例中,您可以从用户那里获取颜色列表并要求他们只提供偶数颜色。
下面的示例使用类似的推理来创建每个包含 5 名学生的小组。在现实生活中,您将不得不使用额外的代码对学生进行分组,但检查学生总数是否为 5 的倍数的基本思想并没有改变。
<?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.'; } ?>
将数字更改为其他数字的倍数
在上一节中,我们使用模运算符告诉用户只提供特定倍数的输入值。如果这不可能,我们还可以强制输入为偶数以及 5 或其他数字的倍数。
模运算符提供第一个数字除以第二个数字后剩下的整数。这意味着从第一个数字中减去余数将使其成为第二个数字的倍数。例如,可以通过取模 28 % 5 将 28 更改为 5 的倍数。在这种情况下,模数将为 3。我们现在可以从原始数字中减去 3,使其成为 5 的倍数。以下line 将 通过从中减去适当的值来强制任何正数 x 成为另一个正数的倍数 。y
x = x - (x % y)
在我们之前有 28 名学生的示例中,我们可以只留下 3 名学生并将其他学生分组。
<?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.'; } ?>
限制输入
正如我在文章开头提到的,在正数的情况下,模运算符将返回一个介于 0 和 N - 1 之间的数字,其中 N 是除数。这意味着您可以对任何输入设置上限,并重复顺序地执行一些操作。这是一个例子:
<?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."; } ?>
在上面的例子中,我们只有五种颜色,但总共有 180 张图像。这意味着我们必须不断循环使用相同的五种颜色并将它们分配给我们所有的图像。模运算符完美地满足了这一需求。它将限制 $i % $color_count在 0 和 (5 - 1) 或 4 之间的值。换句话说,我们可以轻松地依次选择数组的所有颜色。
在循环中每隔 N 次执行一些任务
遍历循环时,我们可以检查每次循环时递增的变量值,并在每第 n 次迭代后执行特定任务。想到的一个实际用例是向用户更新一个长期运行的过程。假设您正在使用 PHP 对 1,000 个不同的图像进行更改。如果更改很大,则此过程将需要一段时间才能更新所有图像。
在这种情况下,用户将无法知道程序是否只是卡住或实际取得了任何进展。您可以做的是在每 10 个图像编辑后向用户报告进度。
<?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.'; } } ?>
上面示例中的 update_images() 函数是完全组成的,但是您可以将其替换为其他过程,例如调整图像大小、添加水印、将它们转换为灰度等。( 如果您想学习如何以编程方式进行,请查看我的 PHP GD 图像编辑教程自己在 PHP 中编辑图像。)
在不同的测量单位之间转换
模运算符也可用于在不同的测量单位之间进行转换。例如,您可以使用它将以秒表示的持续时间更改为以小时、分钟和秒表示的相同持续时间。同样,您也可以将大量厘米转换为公里、米和厘米。这是一个例子:
<?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.''; ?>
我们首先简单地将总秒数除以 3,600 并将值转换为整数。这给了我们总小时数,因为每小时有 3,600 秒。
在下一步中,我们 3600 * $hours 从原始秒数中减去。这消除了我们转换为小时的所有秒数。现在除以 60 将得出总分钟数。最后,我们使用模运算符来获得秒数。
计算两个数的 GCD
您还可以使用模运算符快速计算两个数字的最大公约数 (GCD)。诀窍是不断计算数字的模并重新分配它们,直到它们完全除。
<?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); ?>
我们继续计算 $a%$b如果$b 不完全除 $a。每次计算后,$b 赋值给 $a,我们之前计算的模赋值给$b。$b 当模数变为 0 时的值 就是我们的 GCD。
用模幂计算模数
模指数用于计算机科学的许多领域,如密码学。它依赖于模数的属性,其中:
(a ⋅ b) mod m = [(a mod m) ⋅ (b mod m)] mod m
我们可以根据上述性质创建一个函数来计算 x y 除以 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); ?>
通过首先评估指数 44 123来计算模数 将给我们一个 203 位的数字。如果指数超过 1,000,它会大得多。在这种情况下,使用上述函数将更快地为我们提供模数。
如果除数为 1,则该函数仅返回 0。否则,它运行一个 for 循环以获取$exponent迭代次数并计算每个点的模数。最终结果只是我们通过计算指数表达式的值并取模后得到的余数。
最后的想法
正如您在本教程中看到的,模运算符虽然易于使用,但有很多应用程序。我们通过查看正数和负数的模以及浮点数来开始本教程。在那之后,我们介绍了一些我们将使用模数的常见场景ios 。
- 浮点模数
- 任意精度模数
- 检查一个数字是否是其他数字的倍数
- 将数字更改为其他数字的倍数
- 限制输入
- 在循环中每隔 N 次执行一些任务
- 在不同的测量单位之间转换
- 计算两个数的 GCD
- 用模幂计算模数