C número entero comportamiento de desbordamiento cuando se asignan a los números enteros más grande de ancho

StackOverflow https://stackoverflow.com/questions/728847

Pregunta

Si ejecuto el siguiente código en C:

#include <stdint.h>

uint16_t a = 4000;
uint16_t b = 8000;

int32_t c = a - b;

printf("%d", c);

Se imprime correctamente '-4000' como el resultado. Sin embargo, estoy un poco confundido: ¿no debería haber un desbordamiento aritmético al restar un entero sin signo más grande de la otra? ¿Qué reglas de fundición están en juego aquí? Esta pregunta parece un poco noobish, por lo que cualquier referencia sería muy apreciada.

¿Fue útil?

Solución

La cuestión es en realidad un tanto complicado. Operandos de expresiones aritméticas se convierte usando las reglas específicas que se pueden ver en la Sección 3.2.1.5 de la estándar (C89) . En su caso, la respuesta depende de qué tipo es uint16_t. Si es menor que int, short int decir, a continuación, los operandos se convierten a int y se obtiene -4000, pero en un sistema de 16 bits, uint16_t podría unsigned int y la conversión a un tipo firmado no sucedería automáticamente.

Otros consejos

La respuesta corta es que todos estos son promovidos a int durante la resta. Para la respuesta larga, mira la sección 6.3.1.1 de la C norma, donde se habla de promociones entero en expresiones aritméticas. idioma correspondiente de la norma:

  

Si un int puede representar todos los valores de   el tipo original, el valor es   convertida a un int ; de lo contrario, es   convertida a un unsigned int . Estas   son llamados los promociones enteros .   Todos los demás tipos no se han modificado por el   promociones entero.

Los datos están ahí, también, pero consiguen bastante desagradable.

Los dos operandos son promovidos a int32_t durante la resta. Si el resultado hubiera sido mayor que el valor máximo para int32_t que podría haber obtenido desbordamiento.

Hay, de hecho, un desbordamiento pero C no te dice.

El desbordamiento deja un valor que pasa a ser -4000 cuando se interpreta como un número entero con signo. Esto funciona como se diseñó en las máquinas de complemento a 2.

Trate de interpretar el resultado como sin firmar, y se dará cuenta de que (u1-u2) evalúa a un número aparentemente sin relación, cuando U1

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top