sirve que programming para operator how funcion c gcc modulo

que - ¿Por qué una operación de módulo está devolviendo un valor inesperado?



module operator in c (3)

¿Por qué se imprime el siguiente código 255 ?

#include <stdint.h> #include <stdio.h> int main(void) { uint8_t i = 0; i = (i - 1) % 16; printf("i: %d/n", i); return 0; }

Asumí 15 , aunque i - 1 evalúa como un entero.


Debido a las promociones enteras en el estándar C. Brevemente: cualquier tipo "más pequeño" que int se convierte a int antes de su uso. No puedes evitar esto en general.

Entonces, qué pasa: i es promovido a int . La expresión se evalúa como int (las constantes que utiliza también son int ). El módulo es -1 . Esto luego se convierte a uint8_t : 255 por la asignación.

Para printf entonces i se promueve en enteros a int (de nuevo): (int)255 . Sin embargo, esto no hace daño.

Tenga en cuenta que en C89, para a < 0 , a % b no es necesariamente negativo. Estaba definido por la implementación y podría haber sido 15 . Sin embargo, dado que C99, se garantiza que -1 % 16 sea -1 ya que la división debe producir el cociente algebraico .

Si desea asegurarse de que el módulo dé un resultado positivo, debe evaluar la expresión completa unsigned al lanzar i :

i = ((unsigned)i - 1) % 16;

Recomendación: Habilitar las advertencias del compilador. Al menos la conversión para la asignación debe dar una advertencia de truncamiento.


Esto funciona (muestra 15) con el compilador de Microsoft C (sin stdint.h, así que usé typedef):

#include <stdio.h> typedef unsigned char uint8_t; int main(void) { uint8_t i = 0; i = (uint8_t)(i - 1) % 16; printf("i: %d/n", i); return 0; }

La razón para el 255 es porque (i - 1) se promueve a entero, y la división entera utilizada para% en C redondea hacia cero en lugar de infinito negativo (redondear hacia infinito negativo es la forma en que se hace en matemáticas, ciencias y otros) lenguajes de programación). Entonces, para C% es cero o tiene el mismo signo que el dividendo (en este caso -1% 16 == -1), mientras que en matemáticas el módulo es cero o tiene el mismo signo que el divisor.


Esto se debe a que -1 % n devolvería -1 y NO n - 1 1 . Como i en este caso no tiene signo de 8 bits int, se convierte en 255.

1 1 sobre cómo funciona el módulo para enteros negativos en C / C ++.