jueves, abril 14, 2011

Enteros en C++

Hola,
Hoy (y los próximos días) vamos a ver unas cosas asombrosas, pero que han sido siempre así, aunque la mayoría no lo sepa.

Todos los lenguajes de programación son imperfectos en cierto sentido.

1.-Tenemos una memoria finita.
2.-Los tipos de datos numéricos están limitados.
3.-Nuestros programitas quieren hacer uso de números no limitados.

Esto hace que explorando los límites obtengamos resultados inesperados.

EJEMPLO EN C++:


1.-Normalmente los tipos int (enteros) son de 4 bytes (32 bits).
2.-Si elegimos utilizar un entero con signo (para representar números negativos y positivos) podremos representar este rango:

Desde -2^31 hasta 2^31-1

O lo que es lo mismo:

Desde -2.147.483.648 hasta 2.147.483.647

3.-La representación interna es en complemento a dos.

¿Cómo son los números positivos en complemento a dos?

Los positivos son como siempre:

5 en decimal = 0000 0101 en binario.

¿Cómo son los números negativos en complemento a dos?

Se invierten los 0-s y 1-s (realmente sería sumar un 1 a todos los dígitos ya que 1+1 es 0 igual que 6+4=0 al hacer una suma decimal sin tener en cuenta la llevada).

y después de la inversión se suma un 1.

4 en decimal = 0000 0100
complemento de 4: 1111 1011
complemento más suma: 1111 1100

¿Y la gran ventaja?


Por ejemplo la resta 5 - 4 = 1 se hace por medio de una suma:

0000 0101 + 1111 1100 = 0000 0001

¡Magia!

¿y qué pasa cuando llegamos al límite de los 4 bytes?

supongamos que en nuestro programa numero = 2.147.483.646

hacemos numero++ y obtenemos 2.147.483.647 que es exactamente el límite que hemos indicado antes (2^31-1).

Ahora que estamos en el límite hacemos numero++ y...

nos da -2.147483648.

Explicación:

2.147.483.647 en decimal es 0111 1111 1111.........................1111 en binario.
Recordad que en complemento a dos que el primer dígito sea 0 indica que es un número positivo.

Ahora bien, al sumar un uno obtenemos (¡¡¡Ahora es un número negativo!!!)

1000 0000 0000............................................0000

-2.147.483.648 en complemento a dos.


La prueba:



El programita:



Saludos.

No hay comentarios: