/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Operador complemento a uno

 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
cigoba



Registrado: 27 Ago 2007
Mensajes: 39

MensajePublicado: 27/08/2007 6:11 am
Título: Operador complemento a uno

Hola,
Soy nuevo en C y estoy haciendo algunos programas con los operadores de bits, más precisamente con el operador de negación. Pero en la salida no obtengo los resultados esperados. Y eso me ocurre con los tres IDES con que probé el mismo código (Code::Blocks, Dev-C++, VC++ 6).

Este es el código:

Código:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    printf("Complemento a uno de 0: %d", ~0);   /* Resustado obtenido: -1 */
    putchar('\n');
    printf("Complemento a uno de 1: %d", ~1);   /* Resustado obtenido: -2 */
    putchar('\n');
    printf("Complemento a uno de 2: %d", ~2);   /* Resustado obtenido: -3 */
    putchar('\n');
    printf("Complemento a uno de 152: %d", ~152);   /* Resustado obtenido: -153 */
    putchar('\n');
    system("PAUSE");
    return 0;
}


En teoría:
La primer salida me debería dar: 1 , porque 0 en binario es 0 y su complemento es 1
La segunda: 0 porque 1 en binario es 1 y su complemento es 0
La tercera: 1 porque 2 en binario es 10 y su complemento es 01
La cuarta, según el tutorial de Gorka, debería dar 103

Probé de todo, incluso agregándole el valor absoluto -por las dudas- así:
Código:

...
#include <math.h>
...
printf("Complemento a uno de 152: %d", abs(~152)); /* Resustado obtenido: 153 */
...


Gracias. Surprised
Volver arriba
mamntc02



Registrado: 30 Abr 2007
Mensajes: 242

MensajePublicado: 27/08/2007 6:23 am
Título:

Hola,

te comento el primero, ya q los demás son iguales.

Si tu haces ~0, lo q esperas es q TODOS los bits se inviertan, no? Imagina q tenemos un char (8bits) para hacerlo fácil:

0 = 00000000 (en bits) ==> ~0 = ~(00000000) = 11111111.

Al estar trabajando con char (al igual q con int), éstos son valores con signo, y la manera q hay de indicar esto es poniendo un '1' en el bit de mayor peso. Por tanto ya sabemos q el número es negativo, ahora sólo falta hacer el complemento a 2, para obtener el numero en cuestión. En este caso -1.

Saludos.
Volver arriba
cigoba



Registrado: 27 Ago 2007
Mensajes: 39

MensajePublicado: 27/08/2007 6:51 am
Título:

No entiendo. Dices que debo trabajar con tipos de datos sin signo, por ejemplo unsigned char. Lo hago así:
Código:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    unsigned char a=152;
    printf("Complemento a uno de 152: %d", ~a);   /* Resustado obtenido: -153 */
    puts("\n");
    system("PAUSE");
    return 0;
}


Pero sigo sin obtener el resultado que coloca Gorka en su tutorial.
Podrías colocar el código de tu solución con los mismos valores que puse yo en el primer código?
De lo contrario el ejemplo del Gorka no sirve, al menos para Windows. Shocked
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 3657
Ubicación: Mexico

MensajePublicado: 27/08/2007 7:25 am
Título:

Primero que nada hay que tener cuidado en no confundir el operador de negacion (el '!') con el operador complemento a uno (el '~').

El resultado del operador de negacion (o '!') es uno si su operando es distinto de cero y uno en caso contrario, por ejemplo:
Código:
int resultado;

/* ... */

resultado = !-1; /* almacena cero */
resultado = !0;  /* almacena  uno */
resultado = !2;  /* almacena cero */
resultado = !3;  /* almacena cero */

/* ... */

Este es el mismo resultado que producen los operadores de comparacion ("==" y "!=") y de relacion (">=", ">", etc.) si se cumple o no su condicion: si la condicion se cumple el resultado es uno y si no es asi el resultado es cero.

----

En el caso del operador de complemento a uno (o '~') su operacion ya lo explico mamntc02, hay que recalcar que este operador invierte todos los bits y es por esto que no estas obteniendo los resultados que esperas.

cigoba escribió:
La segunda: 0 porque 1 en binario es 1 y su complemento es 0

El error aqui es pensar que los bits que componen un objeto estan indicados por el numero necesario de bits para expresar el valor y esto no es asi.

Me explico mejor (o eso espero):

La constante literal 1 en C es de tipo "signed int" y este tipo en MS Windows esta constituido de 32 bits ( de nuevo sin importar el valor almacenado) asi que 1 se almacena internamente como:

00000000 00000000 00000000 00000001

Si a este valor le aplicamos el operador de complemento a uno este invierte todos los bits resultando en:

11111111 11111111 11111111 11111110

Y dependiendo de como se representen los numeros negativos (usualmente mediante complemento a dos pero tambien hay la posibilidad de complemento a uno y magnitud con signo) es el resultado impreso por printf.

El caso con la constante literal 2 es similar su patron de bits es:

00000000 00000000 00000000 00000010

Y el operador de complemento a uno resulta en:

11111111 11111111 11111111 11111101

----

cigoba escribió:
La cuarta, según el tutorial de Gorka, debería dar 103

Ese ejemplo del curso de Gorka tiene un error, un listado de los errores del curso se encuentra en esta tema: Compendio de errores, notas y comentarios.

Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
cigoba



Registrado: 27 Ago 2007
Mensajes: 39

MensajePublicado: 27/08/2007 1:23 pm
Título:

Gracias a ambos, ya entendí.
rir3760 muy bueno el compendio que desarrollaste. ¿Por qué no haces un buen tutorial de C estándar? puesto que el de Gorka no es puro ANSI C y utiliza mucho el conio, y esto a un principiante de C le trae ciertas confusiones.

Un saludo. Very Happy
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 3657
Ubicación: Mexico

MensajePublicado: 27/08/2007 5:01 pm
Título:

Tengo planeado empezar en el transcurso de este año un tutorial con licencia Opensource pero honestamente me va a llevar bastante tiempo ...

Las buenas noticias son que Gorka Urrutia planea actualizar su curso en el corto plazo (en estas ultimas semanas anda al parecer muy ocupado con real life issues).

Un saludo
_________________
The capacity to learn is a gift;
The ability to learn is a skill;
The willingness to learn is a choice.
--
Rebec of Ginaz
Volver arriba
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com