Mod y resto no son lo mismo



¡Prepárate, un artículo extremadamente pedante te espera, que bien puede ahorrarte una entrevista o ahorrar unas horas mientras detecta un error en la producción!

Estoy trabajando activamente en la segunda temporada de The Impostor's Guide y escribo sobre el código RSA para SSH, que obviamente es el código más descargado en la historia de TI.

Me gustaría entender completamente esta historia. Quién inventó este código, cómo funciona, por qué funciona y si funcionará en el futuro . Ahora he descubierto una historia muy interesante . No soy criptómano y veo a otros literalmente absorbiendo esta área. Pero también estoy interesado en esto, porque hay pequeños visones en todas partes, y como las urracas me atraen las pequeñas cosas brillantes en los visones profundos . También soy muy bueno en metáforas.

En cualquier caso: la semana pasada aprendí algo extraño y quiero compartir: resulta que ese mod y el resto de la división no son lo mismo . Es realmente divertido que algunos lectores salten de sus asientos y griten con estas palabras: "¡Pero eso es exactamente lo que siempre intenté decirte a ti ya todos los demás!"

¡Llama a los muchachos de la secta "mod no es el resto"! Esto es para ti.

¿Qué es mod?


Tuve que estudiar esto, así como la última vez que surgió ese tema. Esta es una de esas cosas que sabes pero que no recuerdas. Cuando usas mod, luego divide un número por otro y toma el resto. Entonces: 5 mod 2 será 1, porque 5/2 = 2 con el resto de 1.

El término mod significa operación de módulo , con el módulo 2 en este caso. La mayoría de los lenguajes de programación usan % para denotar tal operación: 5 % 2 = 1 .

Ahí es donde entramos en la extraña área gris.

Las matemáticas de la esfera


Recuerdo cómo enseñé esto en la escuela, y luego lo olvidé. Hay un tipo de matemática llamada "aritmética modular" que se ocupa de las estructuras cíclicas. La forma más fácil de imaginar esto es un dial con ciclo 12. Para un matemático, el dial es mod 12 . Si desea comprender si es posible dividir equitativamente 253 horas en días, puede aplicar la operación 253 mod 24 , el resultado será 13 , por lo que la respuesta es no. Podemos responder sí solo si el resultado es 0.

Otra pregunta que puede hacer es: "Si me voy a las 6 de la tarde, ¿a qué hora será a la llegada en 16 horas?" Esto será 6 + 16 mod 12 , es decir, 10.

Los criptógrafos aman el mod , porque cuando se usa con números realmente grandes, puedes crear algo conocido como "funciones unidireccionales". Estas son funciones especiales que facilitan el cálculo de algo en una dirección, pero no en el contrario.

Si te digo que 9 es el resultado de la cuadratura, puedes determinar fácilmente cuál fue la entrada 3. Antes de ver todo el proceso de principio a fin. Si digo que 9 es el resultado del mod 29 , entonces será más difícil entender cuál es la entrada.

A los criptógrafos les gusta esta idea porque pueden usar la división del resto con números primos gigantes para generar claves criptográficas. Esta es una historia completamente diferente: si quieres leer al respecto, puedes comprar un libro o, mejor aún, apoyar mis esfuerzos para escribirlo .

Sin embargo, no nos desviaremos del tema.

Restos y matemática del dial


Ahora vamos al punto: el módulo y el resto simple son los mismos cuando los números son positivos, pero difieren en el caso de los números negativos.

Considere la siguiente tarea:

 const x = 19 % 12; console.log(x); 

¿Cuál es el valor de x ? Divide los números y obtén 7 como el resto de 12. Esta es la respuesta correcta. ¿Qué tal esto?

 const y = 19 % -12; console.log(y); 

Usando las matemáticas ordinarias, podemos multiplicar -12 por -1, lo que da 12, y todavía nos quedan 7, por lo que nuestra respuesta es nuevamente 7.

JavaScript está de acuerdo con esto:



C # también está de acuerdo:



Google está de acuerdo con la primera declaración, pero no está de acuerdo con la segunda:



Ruby está de acuerdo con Google:



En nombre de Dijkstra, ¿qué está pasando aquí?

Hace horas


Para responder la pregunta, debe comprender la diferencia entre el resto y el módulo . Los programadores combinan estas operaciones , pero no deberían hacerlo, porque dan el mismo resultado solo si el divisor (en nuestro caso 12) es positivo. Puede enviar fácilmente errores a producción si el divisor es negativo.

¿Pero por qué hay una diferencia? Considere el divisor positivo 19 mod 12 en el reloj:



Resultado final 7. Sabemos esto y podemos demostrarlo matemáticamente. Pero ¿qué pasa con 19 mod -12 ? Aquí necesitas usar otros relojes :



El módulo es -12, y no podemos ignorarlo o cambiarlo multiplicando por -1, ya que la aritmética modular no funciona de esa manera. La única forma de calcular correctamente el resultado es reorganizar las marcas en el reloj para que podamos movernos desde -12 o girar el reloj en sentido antihorario, lo que da el mismo resultado.

¿Por qué no iniciar etiquetas con -1, mover a -2, etc.? Porque en este caso, retrocederemos y reduciremos constantemente el resultado hasta que alcancemos -12, y en este momento haremos un salto de +12, y el módulo no funciona así.

Esto es una cosa famosa.


Antes de que me llames loco y empieces a buscar en Google un tema: este es un hecho bien conocido . De hecho, la MDN (Mozilla Developer Network) incluso llegó a llamar a % la operación restante, no al módulo:

El operador restante devuelve el resto de dividir un operando por otro. Siempre acepta el signo del dividendo .

Esto es lo que Eric Lippert, uno de los dioses de C #, dice sobre el módulo en C # :

Sin embargo, esto no es en absoluto lo que el operador% realmente hace en C #. El operador% no es un operador de módulo canónico, es un operador restante.

¿Qué hay de tu idioma?

¿Y qué?


Puedo entender si has leído hasta aquí, y ahora te rascas la cabeza y te preguntas si vale la pena preocuparte. Creo que cuesta por dos razones:

  1. Me imagino cómo esta pregunta me tomará por sorpresa en una entrevista.
  2. Me imagino cómo este entra en producción, y los desarrolladores descubrirán durante varias horas por qué las matemáticas no funcionan.

Esto también es un hecho divertido en caso de que aparezca su amigo pedante programador.

Source: https://habr.com/ru/post/es421071/


All Articles