• Domingo 17 de Noviembre de 2024, 17:40

Autor Tema:  Complementos(1 y 2)  (Leído 3998 veces)

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Complementos(1 y 2)
« en: Miércoles 11 de Mayo de 2011, 18:51 »
0
Hola, que tal.

Leyendo un libro, me surgió una duda que no logro aclarar por mas que lo leo.

He leido que en una variable de 8 bits(1 byte), usando un complemento a 2, el rango oscila de -128 a 127, mientras que usando complemento a 1, va de -127 a 127.
Estamos hablando de variables con signo claro.

He mirado el archivo limits.h:

Código: C
  1. #  define CHAR_BIT  8
  2.  
  3. /* Minimum and maximum values a `signed char' can hold.  */
  4. #  define SCHAR_MIN (-128)
  5. #  define SCHAR_MAX 127
  6.  

Así que supongo que usan complemento a 2.

Pero no logro ver porque usando complemento a 2, el numero negativo es -128, mientras que usando 1 es -127.
Por lo que he leido, el C2(complemento 2) es igual a: C1+1, pero no se si va por ahi la cosa. Estoy bastante liado la verdad.

Este es el enlace que estoy leyendo, y que de ahí surgió la duda: http://users.powernet.co.uk/eton/kandr2/krx304.html

No se si me he explicado bien, llevo todo el dia con esto y tengo la cabeza muy espesa ya.

Gracias de antemano

punteroNULO

  • Miembro activo
  • **
  • Mensajes: 73
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #1 en: Miércoles 11 de Mayo de 2011, 19:56 »
0
En este enlace hay una explicación sencilla, y bastante buena,  del cálculo del complemento a dos.

http://es.wikipedia.org/wiki/Complemento_a_dos

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #2 en: Jueves 12 de Mayo de 2011, 10:51 »
0
Hola punteroNulo,

Si, lo he leído como 4 o 5 veces xD, pero no me acabo de aclarar.

Es decir, se que el complemento a 2 se usa para representar los números negativos, invirtiendo los bits después de encontrar el primero 1 a la derecha, o usando el complemento a 1 y sumando 1 luego. Esto lo tengo claro, o creo tenerlo vaya.

Creo entender que en complemento a 2, los números negativos van de -128 a 127(siempre hablando de 1 byte claro), y en cambio en complemento a 1 van de -127 a 127 porque en C1 los números negativos son 2^n-1, mientras que en C2 es 2^n.

De todos modos, lo unico que no acabo de cazar muy bien es el hecho de cuando usar uno u otro, y además, ¿por qué en C se usa C2 ?.
Tal y como dije, en limits.h:

Aparece CHAR_MIN como -128.

Quizá es una duda muy tonta, pero no lo se ver, y también se que esta duda no esta muy relacionada con este ámbito, ya que no pregunto dudas especificas de programación, pero no se me ha ocurrido un lugar más apropiado. Aunque si lo creéis oportuno moved el hilo a otro sitio y disculpad las molestias.

Saludos

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #3 en: Jueves 12 de Mayo de 2011, 14:02 »
0
Buenas

El complemento a 1 de un numero se logra invirtiendo todos los bits del numero, o sea (en caso de 8 bits)  seria como hacer un N XOR 11111111.
Mientras que el complemento a 2 es el complemento a 1 más 1, o sea (N XOR 11111111) + 00000001

El complemento a 2 se empezo a usar ya que ne el complemento a 1 existe una doble represenacion del 0, ( +0 = 00000000 y -0 = 11111111)
Por eso es que en complemento a 2 el rango va de -128 a 127, en vez de -127 a 127. Ya que  C2 no existe esa doble representacion del 0.

Uno no puede elegir si trabajar con un complemento u otro, es como trabaja internamente el procesador

Espero haber podido dejarte todo un poco mas claro.

Saludos
The sweet smell of a great sorrow lies over the land.


Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #4 en: Jueves 12 de Mayo de 2011, 16:09 »
0
Epa, gracias por responder.

Ahora más o menos empiezo a tener una idea bastante clara.

Debido a que en el complemento a 1, existe la doble representación del cero, el rango seria: {-127...-1, -0, 0, 1..., 127}
Mientras en el C2, solo existe una sola representación del cero, tenemos espacio para un byte mas, es decir un numero más, que en este caso es el -128. ¿Es correcto?

EDITO, así no creo una respuesta nueva:

Haciendo unas pruebas sobre lo leído, imaginemos que quiero encontrar el valor en binario del -9.

El 9 en binario es: 1001

Uso el C2:

Código: C
  1. -Torno todos sus bits: 0110
  2. - Le sumo 1: 0111
  3.  

Y le agrego un 1 al bit mas significativo, quedando que:
Código: ASM
  1. 10111 -> -9
  2.  

Sin embargo, usando conversores web para verificarlo, veo que 10111 da 23.

Esto creo que es porque he limitado el numero de bits a 5, pero si lo hiciera con 8, el numero 23 quedaría: 00010111, y el numero -9 en lugar de 0, 1. Voy muy desviado?

Se que el tema se ha desvirtuado mucho, y que poco cabe aquí, lo siento.  :unsure:
 
Gracias y saludos

ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #5 en: Viernes 13 de Mayo de 2011, 03:31 »
0
Citar
Sin embargo, usando conversores web para verificarlo, veo que 10111 da 23.

Esto creo que es porque he limitado el numero de bits a 5, pero si lo hiciera con 8, el numero 23 quedaría: 00010111, y el numero -9 en lugar de 0, 1. Voy muy desviado?

Se que el tema se ha desvirtuado mucho, y que poco cabe aquí, lo siento.  :unsure:
 
Gracias y saludos

Desafortunadamente si, vas muy desviado.

Para empezar, tanto en el complemento a uno como en el complemento a 2, se deben rellenar TODOS los bits no utilizados con cero, dependiendo del tamaño en que los vas a almacenar, quiere decir que suponiendo que almacenas el numero nueve de tu ejemplo en una variable de 8 bits (un byte) el numero 9 en realidad es 00001001, y por lo tanto su complemento a uno es 11110110, y el complemento a 2 es 1110111. Si la variable fuera de 16 bits (2 bytes), el numero seria 0000000000001001, el complemento a uno seria 1111111111110110 y el complemento a 2 seria 1111111111110111.

Ahora, segundo error que tienes, recuerda cuando se utiliza el complemento a 1 y 2, el primer digito indica que el numero es un numero NEGATIVO, no un numero positivo, suponiendo que el numero esta en complemento a 2, 10111 es negativo, ya que su primer digito es uno.

Para obtener el verdadero numero que representa, debes volver a calcular el complemento a 2 del numero en cuestion.

Complemento a 1 de 10111: 01000
Sumandole uno para obtener el complemento a 2: 01001
01001 = 9 y como el primer digito del numero era 1, quiere decir que el numero en realidad es -9

Recapitulando, solo se calcula el complemento a 2, si el primer digito es uno, porque eso significa que el numero es negativo, si el primer digito del numero es cero, no se calcula el complemento, porque quiere decir que el numero es positivo. Recuerda ademas que debes rellenar con ceros hasta tener el total de bits de la variable antes de calcular el complemento, si es que quieres obtener el equivalente negativo de determinado numero.

Ahora otro detalle mas para finalizar, y ya aplicado a lenguaje C/C++, el complemento a 2 solo aplica para aquellas variables que utilizan numeros negativos, o sea las variables (signed) short, int, long int, etc. Recuerda que el complemento a 2 es la manera que tenemos los humanos de poder almacenar y representar un numero negativo en la computadora. En las variables que son unsigned, el primer digito no representa nada, y el numero se toma tal cual.

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #6 en: Viernes 13 de Mayo de 2011, 10:35 »
0
ProfesorX, gracias por tu tiempo.

Por lo que tengo entendido, tanto el complemento a 1 y a 2, ambos solo se usan para buscar y representar números negativos.
Y lo de rellenar con 0's o 1's, me guie por esto que encontre:

" En realidad, un número en complemento a dos se expresa con una cantidad arbitraria de unos a la izquierda, de la misma manera que un número binario positivo se expresa con una cantidad arbitraria de ceros."

Fuente: http://es.wikipedia.org/wiki/Complemento_a_dos

Quizá simplemente lo he interpretado mal.


Sobre esto que diceS:

Citar
Ahora, segundo error que tienes, recuerda cuando se utiliza el complemento a 1 y 2, el primer digito indica que el numero es un numero NEGATIVO, no un numero positivo, suponiendo que el numero esta en complemento a 2, 10111 es negativo, ya que su primer digito es uno.

Uhm, si por ejemplo yo presentara el numero 10111 a alguien, y no le dijera si esta en complemento 1 o 2, uno tiende a pensar que es un numero binario sin mas, el 23.
Ahora, si yo lo presento como: 00010111, o como 11110111, entonces sabrá por el 1 o 0 del principio si se trata de un número negativo, o un numero positivo. Es correcto?

Algo que pensaba que tenia claro, pero viendo esto
Citar
Recapitulando, solo se calcula el complemento a 2, si el primer digito es uno
se me tambalea un poco. El complemento a 2  se usa para encontrar el negativo de un numero positivo en binario, no?
Entonces, si quiero encontrar el numero en binario que representa el -9, tengo que hacer el complemento a 2 del 9, que es lo que hice en el anterior post. Esto es así, o me lo he inventado?

Respecto a lo de C, todo empezó por eso, porque vi un ejercicio donde hablaban sobre esto, y me di cuenta de que yo no tenía ni idea respecto al tema, así que me puse a investigar.
Creo que puse el enlace al principio pero viniendo a resumir, diciendo que no se puede representar en complemento a dos el numero negativo más grande en su valor absoluto. Como CHAR_MIN = -128, no se podría representar el +128.  Y a partir de ahí fui leyendo a poco, pero no se, me cuesta un poco xD

Gracias chicos  ^_^

Epa

  • Miembro MUY activo
  • ***
  • Mensajes: 242
  • Nacionalidad: ar
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #7 en: Viernes 13 de Mayo de 2011, 16:36 »
0
Cre que se va a clarando la cosa, pero todavia hay algo en lo que estas confundido :P

Nosotros cotidianamente usamos el sistema decimal,y para los numeros negativos usamos el signo - adelante del numero.
Los numeros binarios no son mas que numeros en base 2. Si escribis un numero en papel, o se te ocurre empezas a usar el sistema binario, un numero negativo se representa de la misma manera que ne el decimal, con un - adelante. Por ejemplo 22 = 10110(2) y -22 = -10110(2)

El tema del complemento es unicamente para los controladores o procesadores. Como solo funcionan con 0's y 1's se busco la forma de representar el  signo -

Por otro lado, si una pc usa un complemento u otro no es algo que realmente deberia preocuparte como programador. (aunque es bueno saber como funcionan las cosas).

Saludos
The sweet smell of a great sorrow lies over the land.


ProfesorX

  • Moderador
  • ******
  • Mensajes: 796
  • Nacionalidad: mx
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #8 en: Viernes 13 de Mayo de 2011, 16:56 »
0
Cita de: "Leber"
Quizá simplemente lo he interpretado mal.

Si, me parece que si lo habias interpretado mal.

Es correcto lo que dice wikipedia, el numero de bits que uno elige es arbitrario. Tu puedes elegir representar el numero que quieras con 5, 10 20, 30, 40 bits etc., los que tu desees, aunque ya en la practica los numeros solo pueden estar representados con 8, 16 32 y actualmente hasta 64 bits (multiplos de 8, ya que se toma un byte, 8 bits, como medida). Esto depende de la capacidad del procesador. A mayor cantidad de bits, mayor es el numero que puedes representar. Esta es la razon por la que los primeros procesadores solo podian representar un rango maximo de 0 a  255 para numeros sin signo, -128 a 127 si el numero es con signo, y los actuales de 64 bits el rango va de 0 a 18446744073709551616 sin signo,
-9223372036854775808 a 9223372036854775807 si el numero es con signo.

Citar
Uhm, si por ejemplo yo presentara el numero 10111 a alguien, y no le dijera si esta en complemento 1 o 2, uno tiende a pensar que es un numero binario sin mas, el 23.
Ahora, si yo lo presento como: 00010111, o como 11110111, entonces sabrá por el 1 o 0 del principio si se trata de un número negativo, o un numero positivo. Es correcto?

De nuevo y como te dije antes, esto depende de cuantos bits estas eligiendo para almacenar el numero, y de si quieres representar numeros con signo o sin signo. Si en tu ejemplo, utilizas solo 5 bits, el rango que puedes representar es de 0 a 32 sin signo, y de -16 a 15 con signo. Por lo tanto y como ya notaste, y si no lo notaste te lo recalco, 10111 representa 2 numeros, el 23 si eliges numeros sin signo, y -9 s eliges numeros con signo. Entonces 11110111 tambien representa 2 numeros, -9 (de nuevo, pero ahora con 8 bits) si eliges numeros con signo, y 247 si eliges numeros sin signo. En aquellos numeros cuyo primer bit es cero, como podras notar, el numero es el mismo para numeros con o sin signo.

Citar
Algo que pensaba que tenia claro, pero viendo esto
Citar
Recapitulando, solo se calcula el complemento a 2, si el primer digito es uno
se me tambalea un poco. El complemento a 2  se usa para encontrar el negativo de un numero positivo en binario, no?

Exacto, pero recuerda, solo es una forma de representar el numero negativo que quieras. Pero al final, no te compliques tanto, ya que el compilador hace la conversion por ti, no debes preocuparte por convertir el numero negativo que quieras a complemento a 2. Esto te seria util solamente si trabajas con ensamblador o lenguaje maquina.

Saludos :)

NOTA:
==================================================================
Este foro es para ayudar, aprender, compartir... usenlo para eso,
NO SE RESUELVEN DUDAS POR MENSAJE PRIVADO Y MENOS POR CORREO
==================================================================

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #9 en: Viernes 13 de Mayo de 2011, 17:50 »
0
Gracias, creo que me ha quedado algo más claro, a medida de ir leyendo en webs, y las explicaciones aquí expuestas.

Era solo por curiosidad de saber como funcionan las cosas ^_^

Saludos!

Leber

  • Miembro activo
  • **
  • Mensajes: 65
    • Ver Perfil
Re: Complementos(1 y 2)
« Respuesta #10 en: Viernes 13 de Mayo de 2011, 18:08 »
0
Cita de: "Epa"
El tema del complemento es unicamente para los controladores o procesadores. Como solo funcionan con 0's y 1's se busco la forma de representar el  signo -

Por otro lado, si una pc usa un complemento u otro no es algo que realmente deberia preocuparte como programador. (aunque es bueno saber como funcionan las cosas).

Saludos

Entonces el ordenador no entiende  -11011 , no? Si no que cuando le damos un: -9, el ordenador pasa a C2 el valor absoluto del numero que le hemos dado, en este caso 9, para saber como representar internamente el -9. Es así?  

Se que doy bastante la bara, disculpad.  :ouch: