¿Cuál es -1% de 256 donde% es un operador de módulo?

La forma en que funciona la asignación de enteros a un tipo entero sin signo en el lenguaje C es bastante sencilla y sencilla, y mejor aún, es predecible.

Si asigna un número entero M a una variable de un tipo entero sin signo, y si el valor de M no puede representarse en ese tipo entero, entonces elegirá el valor único N que puede representarse en el tipo entero sin signo de destino, de modo que La diferencia entre N y M es un múltiplo exacto del número de valores que puede contener el tipo de objetivo.

En este caso, el tipo de destino (carácter sin signo) puede contener 256 valores. Entonces, cuando asigna cualquier número entero fuera de [0 … 255] en un carácter sin signo, elige el valor único dentro de ese rango de manera que la diferencia entre su número M y el número asignado N sea divisible por 256.

En este caso, M es -1, y el único número N en el rango [0 … 255] tal que NM es un múltiplo exacto de 256 es el número N = 255. Cuando N = 255, la diferencia NM es 256, y ese es el valor que usa.

Tenga en cuenta que lo anterior es una forma puramente matemática para describir el comportamiento. Otra forma de describirlo es representar el número M en la notación binaria del complemento a dos, y luego truncar todos los bits de orden superior que no encajan en el tipo de destino. Sin embargo, si no sabe cuál es la notación binaria del complemento a dos, eso no ayuda mucho.

También tenga en cuenta que la forma en que se describe anteriormente conserva el comportamiento de la suma, resta y multiplicación. Entonces, si tiene dos enteros A y B, sin tener en cuenta ningún rango en particular, entonces todos estos son verdaderos:

  • (unsigned char) (A + B) es igual a (unsigned char) (A) + (unsigned char) (B)
  • (unsigned char) (AB) es igual a (unsigned char) (A) – (unsigned char) (B)
  • (unsigned char) (A * B) es igual a (unsigned char) (A) * (unsigned char) (B)

El comportamiento de división (y módulo) no se conserva.

Si divide 1 por 256, obtiene cero con 1 como resto. Si divide -1 por 256, obtiene cero con -1 como resto, ese es el resultado de -1 % 256

A partir de los detalles, parece que almacenó el resultado (-1) en un carácter sin signo, que produce 255 porque el carácter sin signo contiene valores entre 0 y 255 y se ajusta. La forma estándar de especificar el resultado es lo que obtienes al sumar o restar 256 repetidamente hasta que termines con un valor que esté dentro del rango.

El libro que está leyendo puede estar usando la palabra “módulo” para significar una operación diferente a la que realiza el operador%.

Cuando divide un número a por un número b, obtiene un cociente q y un resto r, de modo que a = b * q + r, y r está entre 0 y b. Si intenta encontrar q y r donde a y b son -1 y 256, rápidamente encontrará que la única posibilidad es q = -1, r = 255.

Sin muchas palabras, una buena manera de quizás “hacerte ver la verdad” 🙂 es la siguiente:

Si x% n = m, entonces (x + n)% n = m, ¿verdad?

Por ejemplo, 9% 4 = 1 y (9 + 4)% 4 = 13% 4 = 1

Entonces, -1% 256 = (-1 + 256)% 256 = 255% 256 = 255.

Tome un reloj con 256 divisiones en lugar del habitual 12. Coloque la manecilla de los minutos a las 256 en punto. Ahora muévalo 1 marca en sentido antihorario (es decir, configúrelo en -1).

¿A qué número apunta?

si asigna -1 a un carácter sin signo, y el carácter se define como 1 byte (esto puede ser una suposición), el valor será 255. Ambos tienen la representación de 1111 1111, en 8 bits.

En cuanto al módulo 256, eso solo toma los 8 bits más bajos. Por lo tanto, si tiene -1 en diferentes tamaños:

8 bits: 1111 1111

16 bits: 1111 1111 1111 1111

32 bits: 1111 1111 1111 1111 1111 1111 1111 1111

tenga en cuenta que si toma los 8 bits inferiores (es decir,% 256), todos producen:

1111 1111

que en 255 en un byte sin signo.