En este código de abajoalmacenar números negativos
int main()
{
int a = -1;
printf("%d",a>>1);
return 0;
}
¿Por qué se está dando salida -1.
En este código de abajoalmacenar números negativos
int main()
{
int a = -1;
printf("%d",a>>1);
return 0;
}
¿Por qué se está dando salida -1.
el desplazamiento de bit se define solo en los tipos sin signo, para los tipos con signo está definido por la implementación. Y esto es un refinamiento útiles por R ..
Estrictamente hablando, se define por tipos firmados cuando el valor es positivo y el resultado no desbordamiento y desplazamiento a la derecha es definida por la aplicación valores negativos . desplazamiento a la izquierda, por el contrario, no está definida para valores negativos
┌───┬──────────────┬──────────────────────────────────┬────────────────────────┐
│ │ Unsigned │ Signed, positive │ Signed, negative │
├───┼──────────────┼──────────────────────────────────┼────────────────────────┤
│<< │ well-defined │ well-defined, except on overflow │ undefined behaviour │
│>> │ well-defined │ well-defined │ implementation-defined │
└───┴──────────────┴──────────────────────────────────┴────────────────────────┘
Estrictamente hablando, se define para tipos con signo siempre que el valor sea positivo y el resultado no se desborde, y el desplazamiento a la derecha sea definido por la implementación para valores negativos. El desplazamiento a la izquierda, por otro lado, está * indefinido * para los valores negativos. –
Creo que sería "definido por la implementación" en C99 de acuerdo con [Wikipedia: Cambio aritmético] (http: //en.wikipedia.org/wiki/Arithmetic_shift) – Mat
Debido a -1 es 1111111 ... 111 en binario. a>>1
operación "extenderá" signo el bit de signo, por lo que obtiene 1111111 ... 111 de nuevo.
Esto es solo en código complementario, que no es necesariamente la forma en que se representan los números. Pero aún así, en muchas plataformas tiene razón –
@Arment - De acuerdo, definitivamente depende de la máquina. Debería haberlo señalado. Claramente, sin embargo, firmar extender es lo que está sucediendo en este caso particular. –
@Armen - No sé si recibiste comentarios previos. (Disculpe, escriba su nombre.) –
La mayoría de los compiladores eligen interpretar >>
en números con signo para ser desplazamiento aritmético. Por lo tanto, dado que el número es inicialmente negativo (es decir, el bit MSB es 1), después de un desplazamiento a la derecha, ese bit se reemplaza por otro 1 para conservar el signo, por lo que termina con -1 cuando comenzó.
El operador >>
en un valor con signo puede realizar un desplazamiento aritmético o lógico, según el compilador. Los cambios aritméticos retienen el bit de signo, por lo que -1
(que en una máquina complementaria de 2 s, que en estos días es prácticamente la única variedad que encontrará) seguirá siendo -1
cuando se desplaza a la derecha. (Tenga en cuenta que el estándar C explícitamente no especifica si >>
en un número firmado es un cambio aritmético o lógico. Sin embargo, siempre es un cambio lógico en números sin signo)
La definición de cambio de bit en valores con signo es depende de la implementación. Compruebe los documentos de su compilador para saber cómo lo maneja.
En memoria número entero con signo almacenado como complemento 2 si sign int y cuando se leen datos de la memoria {% d} se convierte a formato original así que aquí 2 complemento de -1 se almacenará en memoria, digamos entero tomar 2 bytes 2's complement of -1 is 1111 1111 1111 1111
Después de realizar a>>1
se va a cambiar 0111 1111 1111 1111
ahora como sabemos que cuando se leen los datos de la memoria se convierte de nuevo a 0 complemento a fin de tomar el complemento de 0111 1111 1111 1111
de 2 será como 1000 0000 0000 0001
que es igual a -1
Nota: Complemento 2 de +ve
número es el mismo que el complemento de representación binaria original 2 es solo para -ve
número. En C número siempre almacenado como complemento de 2 forma
Primero, los números sin firmar no se almacenan como complemento a 2. Para números con signo, no todas las arquitecturas/implementaciones del compilador también usan el complemento 2. C estándar permite cualquier otra codificación numérica aunque es casi imposible encontrar un complemento de 1 o una implementación de magnitud de signo actualmente –
@ LưuVĩnhPhúc: por qué su salida es -1 si no está firmado no está almacenado como complemento 2 #include
los números sin firmar se imprimen por '% u', obtendrá un comportamiento indefinido –
Consulte esta pregunta [operador de desplazamiento en C] (http://stackoverflow.com/questions/7622/shift-operator-in-c). – Mat