Módulo en Rust: no lo confundas con el resto de la división

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: ¿por qué la pregunta sobre el módulo es tan popular?

\n\n

Si alguna vez has escrito código en Rust y te has encontrado con números negativos, seguramente te habrás preguntado: «¿Dónde está la función de módulo?». En Stack Overflow, esta pregunta ha acumulado miles de visitas, y no es para menos. Resulta que el operador % en Rust no es el módulo (modulus), sino el resto de la división (remainder). La diferencia es sutil, pero crítica, especialmente en algoritmos, criptografía o al trabajar con estructuras cíclicas.

\n\n

En este artículo, analizaremos en qué se diferencia el módulo matemático del resto, cómo maneja Rust los números negativos y cómo escribir tu propia función para calcular el módulo verdadero. El artículo está orientado a principiantes, pero también será útil para desarrolladores experimentados que quieran refrescar conocimientos.

\n\n

Resumen del contenido

\n
    \n
  • Qué es el módulo y el resto: diferencia matemática
  • \n
  • Por qué % en Rust no es el módulo
  • \n
  • Cómo escribir una función de módulo en Rust
  • \n
  • Ejemplos de la vida real: índices cíclicos y hashes
  • \n
  • Conclusiones y consejos prácticos
  • \n
\n\n

Matemáticas: módulo vs resto

\n\n

Empecemos por lo básico. En matemáticas, el módulo (modulus) es una operación que devuelve un número no negativo, menor que el divisor. Por ejemplo:

\n
    \n
  • 7 mod 3 = 1 (7 se divide entre 3 con resto 1)
  • \n
  • -7 mod 3 = 2 (porque -7 = 3 * (-3) + 2)
  • \n
\n\n

El resto de la división (remainder) es lo que queda después de la división entera. En la mayoría de los lenguajes de programación (C, C++, Java, Rust), el operador % devuelve precisamente el resto, que puede ser negativo si el dividendo es negativo. Ejemplo:

\n
    \n
  • 7 % 3 = 1 (coincide)
  • \n
  • -7 % 3 = -1 (en Rust, porque -7 / 3 = -2, resto -1)
  • \n
\n\n

¿Para qué sirve esto? Imagina que estás programando un reloj: la hora va de 0 a 23. Si son las 22 horas y sumas 5 horas, obtienes las 3 de la mañana. Esto funciona con el módulo: (22 + 5) mod 24 = 3. Pero si usas el resto, con valores negativos todo se rompe. Por ejemplo, (-3) % 24 en Rust dará -3, no 21.

\n\n

Por qué el operador % en Rust es remainder

\n\n

En Rust, el operador % está definido como resto de la división. Esto está fijado en la documentación y en el comportamiento de la biblioteca estándar. La razón es histórica: así se hace en C y en muchos otros lenguajes. Rust sigue el principio de «explícito es mejor que implícito», pero aquí los principiantes suelen caer en una trampa.

\n\n
fn main() {\n    println!("7 % 3 = {}", 7 % 3);   // 1\n    println!("-7 % 3 = {}", -7 % 3); // -1\n    println!("7 % -3 = {}", 7 % -3); // 1 (sí, el signo del divisor no afecta)\n    println!("-7 % -3 = {}", -7 % -3); // -1\n}
\n\n

Observa: el signo del resultado siempre coincide con el signo del dividendo. Esto no es el módulo. Para el módulo verdadero, el resultado debe ser siempre no negativo.

\n\n

¿Cómo escribir una función de módulo verdadero en Rust?

\n\n

La biblioteca estándar de Rust no proporciona una función incorporada para el módulo (a diferencia de Python, donde % funciona como módulo). Pero escribirla es muy sencillo. Aquí tienes la forma más común: mediante el resto con corrección.

\n\n

Función modulus para números enteros

\n\n
fn modulus(a: i32, b: i32) -> i32 {\n    let r = a % b;\n    if r < 0 { r + b.abs() } else { r }\n}\n\nfn main() {\n    println!("modulus(7, 3) = {}", modulus(7, 3));   // 1\n    println!("modulus(-7, 3) = {}", modulus(-7, 3)); // 2\n    println!("modulus(7, -3) = {}", modulus(7, -3)); // 1 (el módulo siempre es no negativo)\n    println!("modulus(-7, -3) = {}", modulus(-7, -3)); // 2\n}
\n\n

Cómo funciona: tomamos el resto a % b. Si es negativo, sumamos el valor absoluto

Blogs

Book Recommendations