2010-04-26 16 views
60

Tenía curiosidad por saber qué pasaría si asignaba un valor negativo a una variable sin firmar.¿Qué sucede si asigno un valor negativo a una variable sin firmar?

El código se verá algo así.

unsigned int nVal = 0; 
nVal = -5; 

No me dio ningún error de compilación. Cuando ejecuté el programa, ¡el nVal recibió un valor extraño! ¿Podría ser que el valor de complemento de 2 se asigne a nVal?

+1

Mi presentimiento de la 2 (no han podido encontrarlo en el estándar todavía) es que el comportamiento es técnicamente indefinido. Además, sospecho que verá lo que espera en casi cualquier compilador que pueda encontrar. Entonces, aunque normalmente verá ese comportamiento, probablemente no sea una buena idea contar con él. – sblom

+5

No está indefinido (ver * §4.7/2 *), pero la representación (por ejemplo, el complemento 2s) no es un mandato de la norma. –

+0

@gf (et al a continuación), genial. Parece que el comportamiento está, de hecho, explícitamente definido para ser lo que esperabas, @viswanathan. – sblom

Respuesta

50

para la respuesta oficial - Sección 4.7 [conv.integral]

"Si el tipo de destino no está firmado, el valor resultante es el menos entero sin signo congruente con el entero de origen (módulo 2^n donde n es el número de bits utilizados para representar el tipo sin signo). [Nota: en una representación de complemento a dos, esta conversión es conceptual y no hay cambio en el patrón de bits (si no hay truncamiento). -finalizar nota]

+27

¿Qué significa * el entero menos sin signo congruente con el entero de origen *? –

+6

@ DavidRodríguez-dribeas Como ejemplo, 5 y 3 son "mod congruente 2" ya que 5% 2 y 3% 2 son ambos 1. – JoeQuery

4

Se mostrará como un número entero positivo de valor máximo de entero sin signo - 4 (el valor depende de la arquitectura de la computadora y el compilador).

Por cierto
Usted puede comprobar esto escribiendo un programa tipo "hola mundo" en C++ simple y ver por sí mismo

+0

Escribí y verifiqué que por eso hice la pregunta, pero no sabía cómo el compilador llegó a ese valor positivo. Gracias – ckv

1

Sí, estás en lo correcto. El valor real asignado es algo así como todos los bits establecidos, excepto el tercero. -1 es todos los bits configurados (hex: 0xFFFFFFFF), -2 son todos los bits excepto el primero y así sucesivamente. Lo que vería probablemente sea el valor hexadecimal 0xFFFFFFFB que en decimal corresponde a 4294967291.

+3

Bit no tiene nada que ver con eso, no se especifica la representación entera. – GManNickG

+1

Tu respuesta es correcta, rigurosa, al grano y algo que nunca usaría en clase. – Martin

+0

ver mi respuesta para el complemento de 2 de -5. No creo que hayas hecho tus cálculos correctamente en los valores binarios aquí. – cynistersix

4

Tiene razón, el entero con signo se almacena en forma de complemento a 2, y el entero sin signo se almacena en unsigned binary representation. C (y C++) no distingue entre los dos, por lo que el valor con el que termina es simplemente el valor binario sin signo de la representación binaria del complemento de 2.

+14

Puede que no se almacene en el complemento 2. – GManNickG

+0

¿Qué significa si algo está "almacenado en 2?" @GManNickG – JeremyF

+3

@JeremyF: No es "2's", "cumplido de 2". Es un término apto para Google y una forma de representar enteros con signo. – GManNickG

21

Asignará el patrón de bits que representa -5 (en complemento a 2) al int sin signo. Que será un gran valor sin signo. Para 32 bits enteros esto será 2^32 - 5 ó 4294967291

+1

Bit no tiene nada que ver con eso. – GManNickG

+9

@GMan: La cita en su respuesta contiene la palabra "bits" ... –

+0

@BenVoigt: De acuerdo, quise decir que no tenía nada que ver con la forma en que se interpretan los bits. (Es decir, los "bits" en la parte citada son solo abreviaciones de 'ceil (log_2 (x))'.) – GManNickG

1

Esto es lo que he ejecutado en Objective-C iOS 4.3

unsigned long testValue = 0; 

NSLog(@"The value is: %lu", testValue); 
testValue -= 5; 
NSLog(@"The new value is: %lu", testValue); 

salida a la consola:

The value is: 0 
The new value is: 4294967291 

El nuevo valor en hexadecimal es 0xfffffffb

Cuál es el complemento de -5

Cuestiones relacionadas