suma signos resta que polinomios operaciones números numeros negativos multiplicación menos mayor jerarquia enteros ejercicios ejemplos división con combinadas aritmeticos agrupacion c gcc unsigned signed

signos - Operación de comparación en enteros sin signo y con signo



polinomios aritmeticos sin signos de agrupacion ejercicios (6)

El hardware está diseñado para comparar firmado a firmado y sin firmar a sin firmar.

Si desea el resultado aritmético, primero convierta el valor sin firmar a un tipo firmado más grande. De lo contrario, el compilador supondrá que la comparación es realmente entre valores sin signo.

Y -1 se representa como 1111..1111, por lo que es una cantidad muy grande ... La más grande ... Cuando se interpreta como sin signo.

Ver este fragmento de código

int main() { unsigned int a = 1000; int b = -1; if (a>b) printf("A is BIG! %d/n", a-b); else printf("a is SMALL! %d/n", a-b); return 0; }

Esto le da la salida: a es PEQUEÑO: 1001

No entiendo lo que está pasando aquí. ¿Cómo funciona el operador> aquí? ¿Por qué es "a" más pequeño que "b"? Si de hecho es más pequeño, ¿por qué obtengo un número positivo (1001) como diferencia?


En una implementación típica donde int es de 32 bits, -1 cuando se convierte a unsigned int es 4,294,967,295 que es de hecho ≥ 1000.

Incluso si tratas la resta en un mundo unsigned , 1000 - (4,294,967,295) = -4,294,966,295 = 1,001 que es lo que obtienes.

Es por eso que gcc escupe una advertencia cuando compara unsigned con signed . (Si no ve una advertencia, pase el -Wsign-compare .)


Encuentre una manera fácil de comparar, quizás útil cuando no puede deshacerse de la declaración sin firmar, (por ejemplo, [NSArray count]), simplemente fuerce el "unsigned int" a un "int".

Por favor, corríjame si estoy equivocado.

if (((int)a)>b) { .... }


Está haciendo una comparación sin signo, es decir, comparando 1000 a 2 ^ 32 - 1.

La salida está firmada debido a% d en printf.

NB algunas veces el comportamiento al mezclar operandos con y sin firma es específico del compilador. Creo que es mejor evitarlos y hacer moldes en caso de duda.


Las operaciones binarias entre diferentes tipos integrales se realizan dentro de un tipo "común" definido por las llamadas conversiones aritméticas habituales (consulte la especificación del lenguaje, 6.3.1.8). En su caso, el tipo "común" unsigned int tiene unsigned int . Esto significa que int operando (su b ) se convertirá a unsigned int antes de la comparación, así como también para realizar la resta.

Cuando -1 se convierte en unsigned int el resultado es el valor unsigned int máximo unsigned int posible (igual que UINT_MAX ). Huelga decir que va a ser mayor que su valor de 1000 sin firmar, lo que significa que a > b es de hecho falso y a es de hecho pequeño en comparación con (unsigned) b . El if en tu código debería resolverse en la rama else , que es lo que observaste en tu experimento.

Las mismas reglas de conversión se aplican a la resta. Su ab realmente se interpreta como a - (unsigned) b y el resultado tiene el tipo unsigned int . Tal valor no se puede imprimir con el especificador de formato %d , ya que %d solo funciona con valores firmados . Su intento de imprimirlo con %d da como resultado un comportamiento indefinido, por lo que el valor que ve impreso (aunque tiene una explicación determinista lógica en la práctica) no tiene sentido desde el punto de vista del lenguaje C.

Editar: En realidad, podría estar equivocado sobre la parte de comportamiento indefinido. Según la especificación del lenguaje C, la parte común del rango del tipo entero con signo y sin signo correspondiente tendrá una representación idéntica (lo que implica, de acuerdo con la nota al pie 31, "intercambiabilidad como argumentos a funciones"). Entonces, el resultado de la expresión a a - b es unsigned 1001 como se describió anteriormente, y a menos que me falta algo, es legal imprimir este valor específico sin signo con %d specifier, ya que cae dentro del rango positivo de int . La impresión (unsigned) INT_MAX + 1 con %d no estaría definida, pero 1001u está bien.


mientras se compara a> b donde a es unsigned int type yb es int type, b es type casted a unsigned int entonces, signed int value -1 se convierte a MAX value of unsigned ** (rango: 0 a (2 ^ 32) -1) ** Por lo tanto, a> b ie, (1000> 4294967296) se vuelve falso. Por lo tanto, else loop printf ("a es PEQUEÑO!% D / n", ab); ejecutado.