Cómo utilizar el operador de módulo en PHP
Spanish (Español) translation by Rene Soto (you can also view the original English article)
PHP tiene un total de ocho operadores aritméticos. Los más comunes son la suma (+), la resta (-), la multiplicación (*) y la división (/). Un operador ligeramente menos conocido, aunque todavía muy importante, es el módulo (%). En este tutorial, nos centraremos en el operador de módulo. Vamos a discutir lo que hace y algunos de sus usos prácticos.
¿Qué hace el operador de módulo?
Si tiene dos variables $a y $b, el cálculo de $a% $b (generalmente pronunciado como "a módulo b" o "a mod b") le dará el resto después de dividir $a por $b. Módulo es un operador de enteros, por lo que convierte ambos operandos en enteros antes de calcular el resto. Entonces, básicamente, el módulo hace la división entera y luego devuelve lo que queda del dividendo.
El signo del valor devuelto por una operación de módulo está determinado por el signo del dividendo. En la división, el resultado después de dividir dos números negativos será un número positivo. Sin embargo, ese no es el caso con el operador de módulo. El signo del divisor no tiene efecto en el valor final.
Aquí hay un par de ejemplos:
1 |
<?php
|
2 |
|
3 |
echo 1089 % 37; |
4 |
// Output: 16
|
5 |
|
6 |
echo 1089 % -37; |
7 |
// Output: 16
|
8 |
|
9 |
echo -1089 % 37; |
10 |
// Output: -16
|
11 |
|
12 |
echo -1089 % -37; |
13 |
// Output: -16
|
14 |
|
15 |
echo -55.4 % -4.2; |
16 |
// Output: -3
|
17 |
|
18 |
echo -55.9 % -4.8; |
19 |
// Output: -3
|
20 |
|
21 |
echo -55 % -4; |
22 |
// Output: -3
|
23 |
|
24 |
?>
|
Módulo de Punto Flotante
Si desea calcular el resto cuando dos números de punto flotante se dividen entre sí, deberá utilizar la función fmod ($dividendo, $divisor). Devuelve el resto de punto flotante después de la división. El valor restante tendrá el mismo signo que el dividendo, y su magnitud será menor que el divisor. Los tres números están relacionados de la siguiente manera:
1 |
$dividend = i*$divisor + $remainder |
Aquí, el
valor i siempre será un entero.
Debe recordar que la aritmética de punto flotante no siempre es precisa debido a las limitaciones de la representación binaria o decimal de las fracciones. Por ejemplo, 1/3 no se puede representar con precisión en forma decimal. Puedes seguir escribiendo 0.33333 ... pero en algún momento deberías parar. Se acercará más al valor original con cada 3 adicionales en la representación decimal, pero el valor aún no será exactamente 1/3.
Este tipo de inexactitud causa problemas con la función fmod(): los resultados no son completamente confiables.
Aquí hay
algunos ejemplos de la función fmod():
1 |
<?php |
2 |
|
3 |
echo fmod(18.8, 2); |
4 |
// Output: 0.8 |
5 |
|
6 |
echo fmod(18.8, 0.2); |
7 |
// Output: 0.2 |
8 |
|
9 |
?> |
El segundo valor no es exacto porque 0.2 se divide perfectamente en 18.8. Esto es solo un defecto de los cálculos en el formato de punto flotante utilizado por las computadoras.
Usos del Módulo Operador
En este tutorial, nos restringiremos a un módulo de enteros porque es mucho más común y tiene muchas aplicaciones.
Comprobando si un número es un múltiplo de algún otro número
El resultado del operador de módulo es cero si el primer número es perfectamente divisible por el segundo número. Esto podría usarse para verificar si un número es un múltiplo del otro en un par de números dado. Probablemente el uso más común de esta propiedad del operador de módulo es para verificar si un número es par o impar. Aquí hay un ejemplo:
1 |
<?php
|
2 |
|
3 |
$colors = ['violet', 'indigo', 'blue', 'green', 'yellow', 'orange', 'red']; |
4 |
$color_count = count($colors); |
5 |
|
6 |
if($color_count % 2 == 0) { |
7 |
echo 'We have created some color pairs for you.'; |
8 |
} else { |
9 |
echo 'Please specify one more or one less color to make pairing possible.'; |
10 |
}
|
11 |
|
12 |
?>
|
En el ejemplo anterior, podría obtener la lista de colores de un usuario y pedirle que solo proporcione un número par de colores.
El siguiente ejemplo utiliza un razonamiento similar para crear grupos con 5 estudiantes cada uno. En la vida real, tendrá que usar un código adicional para agrupar a los estudiantes, pero la idea básica de verificar si el total de estudiantes son múltiplos de 5 no cambia.
1 |
<?php
|
2 |
|
3 |
$total_students = 25; |
4 |
|
5 |
if($total_students % 5 == 0) { |
6 |
echo 'Each group of five students has been given an assignment.'; |
7 |
} else { |
8 |
echo 'Sorry, it is impossible to create groups of five students right now. Please get more students.'; |
9 |
}
|
10 |
|
11 |
?>
|
Cambiar números para ser un múltiplo de otro número
En la sección anterior, utilizamos el operador de módulo para informar a los usuarios que solo proporcionen valores de entrada en ciertos múltiplos. Si eso no es posible, también podemos forzar que la entrada sea igual de bien como un múltiplo de 5 o algún otro número.
El operador de módulo proporciona el número entero que queda después de dividir el primer número por el segundo número. Esto significa que restar el resto del primer número lo convertirá en un múltiplo del segundo número. Por ejemplo, 28 se puede cambiar para que sea un múltiplo de 5 tomando el módulo 28% 5. En este caso, el módulo será 3. Ahora podemos restar 3 del número original para hacer un múltiplo de 5. Lo siguiente la línea forzará a cualquier número positivo x a ser un múltiplo de otro número positivo y restándole un valor apropiado.
1 |
x = x - (x % y) |
En nuestro ejemplo anterior con 28 estudiantes, podríamos simplemente dejar a 3 estudiantes fuera y agrupar a otros estudiantes.
1 |
<?php
|
2 |
|
3 |
$total_students = 28; |
4 |
|
5 |
if($total_students % 5 == 0) { |
6 |
echo 'Each group of five students has been given an assignment.'; |
7 |
} else { |
8 |
$removed_students = $total_students % 5; |
9 |
$total_students -= $removed_students; |
10 |
echo 'We have created groups of five students by removing the last '.$removed_students.' students from the list.'; |
11 |
}
|
12 |
|
13 |
?>
|
Ponga un límite en la entrada
Como mencioné al comienzo de la publicación, en el caso de números positivos, el operador de módulo devolverá un número entre 0 y N - 1, donde N es el divisor. Esto significa que puede poner un límite a cualquier entrada y realizar algunas operaciones de forma repetitiva y secuencial. Aquí hay un ejemplo:
1 |
<?php
|
2 |
|
3 |
$colors = ['violet', 'indigo', 'blue', 'green', 'yellow']; |
4 |
|
5 |
$color_count = count($colors); |
6 |
$total_images = 180; |
7 |
$background_color = ''; |
8 |
|
9 |
for($i = 0; $i < $total_images; $i++) { |
10 |
$background_color = $colors[$i % $color_count]; |
11 |
echo "Setting image background color to $background_color."; |
12 |
}
|
13 |
|
14 |
?>
|
En el ejemplo anterior, tenemos solo cinco colores pero un total de 180 imágenes. Esto significa que tendremos que seguir repitiendo los mismos cinco colores y asignarlos a todas nuestras imágenes. El modulo operador se adapta perfectamente a esta necesidad. Restringirá el valor de $i% $color_count entre 0 y (5 - 1) o 4 inclusive. En otras palabras, podremos elegir secuencialmente todos los colores de nuestra matriz muy fácilmente.
Haz un poco de tarea cada enésima vez en un bucle
Al atravesar un bucle, podemos verificar el valor de una variable incrementada con cada paso a través del bucle y realizar una tarea específica después de cada enésima iteración. Un caso de uso práctico que viene a la mente es actualizar a los usuarios acerca de un proceso de larga ejecución. Digamos que estás haciendo cambios a 1,000 imágenes diferentes usando PHP. Si los cambios son significativos, este proceso tomará un tiempo para actualizar todas las imágenes.
En tales casos, los usuarios no tendrán forma de saber si el programa está bloqueado o si realmente está progresando. Lo que podría hacer es informar el progreso a los usuarios después de editar cada décima imagen.
1 |
<?php
|
2 |
|
3 |
$total_images = 1000; |
4 |
|
5 |
for($i = 1; $i <= $total_images; $i++) { |
6 |
update_images($image_resource); |
7 |
if($i % 10 == 0) { |
8 |
$percent = $i*100/$total_images; |
9 |
echo 'Already processed '.$percent.'% images.'; |
10 |
}
|
11 |
}
|
12 |
|
13 |
?>
|
La función update_images() en el ejemplo anterior está completamente integrada, pero puede reemplazarla con otros procesos como cambiar el tamaño de las imágenes, agregar marcas de agua, convertirlas en escala de grises, etc. (Consulte mis tutoriales de edición de imágenes de PHP GD si desea aprender cómo editar imágenes mediante programación usted mismo en PHP.)
Convertir entre diferentes unidades de medida
El operador
de módulo también se puede utilizar para convertir entre diferentes unidades de
medida. Por ejemplo, podría usarlo para cambiar la duración del tiempo
expresada en segundos a la misma duración expresada en horas, minutos y
segundos. Del mismo modo, también puede convertir una gran cantidad de centímetros en kilómetros, metros y centímetros. Aquí hay un ejemplo:
1 |
<?php
|
2 |
|
3 |
$total_seconds = 32987; |
4 |
|
5 |
$hours = (int)($total_seconds / 3600); |
6 |
$minutes = (int)(($total_seconds - 3600 * $hours )/60); |
7 |
$seconds = $total_seconds % 60; |
8 |
|
9 |
echo 'Hours:'.$hours.' Minutes:'.$minutes.' Seconds:'.$seconds.''; |
10 |
|
11 |
?>
|
Comenzamos simplemente dividiendo el número total de segundos por 3,600 y convirtiendo el valor en un entero. Esto nos da el número total de horas, ya que cada hora tiene 3,600 segundos.
En el siguiente paso, restamos 3600 * $horas del número original de segundos. Esto elimina todos los segundos que hemos convertido en horas. Dividir por 60 ahora nos dará el número total de minutos. Finalmente, usamos el operador de módulo para obtener el número de segundos.
Conclusiones
Como vio en este tutorial, el operador de módulo, aunque fácil de usar, tiene muchas aplicaciones. Comenzamos este tutorial mirando el módulo de los números positivos y negativos, así como los flotadores. Después de eso, cubrimos algunos escenarios comunes donde usaríamos el módulo.
Si tiene alguna pregunta relacionada con este tutorial, hágamelo saber en los comentarios. ¿Tienes algún otro uso de módulo en mente? Por favor compártelos con otros lectores publicándolos en los comentarios.



