unary operator examples bitwise c unary-operator

c - examples - unary operator java



C: comportamiento de operador unitario negativo con operandos sin signo (3)

Parece que no puedo encontrar las partes relevantes en el estándar C que definan completamente el comportamiento del operador unario menos con operandos sin signo.

El estándar de C ++ de 2003 (sí, C ++, tenga paciencia conmigo durante unas pocas líneas) dice en 5.3.1c7: The negative of an unsigned quantity is computed by subtracting its value from 2^n, where n is the number of bits in the promoted operand.

El estándar C de 1999, sin embargo, no incluye una declaración tan explícita y no define claramente el comportamiento unario ni en 6.5.3.3c1.3 ni en 6.5c4. En el último dice Some operators (the unary operator ~, and the binary operators <<, >>, &, ^, and |, ...) ... return values that depend on the internal representations of integers, and have implementation-defined and undefined aspects for signed types.) , que excluye el menos unario y las cosas parecen seguir siendo vagas.

Esta pregunta anterior se refiere al libro K&R ANSI C, sección A.7.4.5 que dice The negative of an unsigned quantity is computed by subtracting the promoted value from the largest value of the promoted type and adding one .

¿Cuál sería el estándar C de 1999 equivalente a la cita anterior del libro?

6.2.5c9 dice: A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

¿Es asi? ¿O hay algo más que me falta?


El comportamiento del operador unario negativo en operandos sin signo no tiene nada que ver con si una máquina utiliza una aritmética de dos complementos con números con signo. En cambio, dado unsigned int x,y; la declaración y=-x; hará que y reciba el valor que tendría que mantener para que x+y igual a cero. Si x es cero, y también será cero. Para cualquier otro valor de x , será UINT_MAX-x+1 , en cuyo caso el valor aritmético de x+y será UINT_MAX+1+(yy) que, cuando se asigna a un unsigned integer , tendrá UINT_MAX+1 sustraído de ella, rindiendo cero.


En cada implementación que conozco, un negativo se calcula como complemento de dos ...

int a = 12; int b = -a; int c = ~a + 1; assert(b == c);

... así que realmente no hay diferencia física entre enteros sin signo con signo negativo y negativo - la única diferencia es en cómo se interpretan .

Entonces en este ejemplo ...

unsigned a = 12; unsigned b = -a; int c = -a;

... los b van a contener exactamente los mismos bits. La única diferencia es que b se interpreta como 2 ^ 32-12 (o 2 ^ 64-12), mientras que c se interpreta como "normal" -12.

Por lo tanto, un negativo se calcula exactamente de la misma manera, independientemente de la "firma", y la conversión entre sin signo y firmado es en realidad un no-op (y nunca puede causar un desbordamiento en el sentido de que algunos bits deben ser "cortados -apagado").


Sí, 6.2.5c9 es exactamente el párrafo que buscó.