Hasta ahora hemos considerado que en la representación binaria tienes todas las posiciones que quieras* (como cuando escribes en un papel, siempre puedes añadir más dígitos).
Ahora vamos a considerar la condición de que sólo tienes una cantidad de dígitos fijos. Esto introduce un nuevo problema el problema del desbordamiento, que es qué ocurre cuando agotas la capacidad disponible.
El desbordamiento ocurre cuando el número que intentamos representar es mayor que el valor máximo que puede ser almacenado en el contenedor dado. En este caso, la variable desborda, y vuelve a 0.
El problema del desbordamiento no es único del sistema binario. También te pasa, por ejemplo, si tienes un candado con combinación que tiene sólo 4 dígitos. Cuando pases el 9999
, volverás al 0000
.
En binario os vais a encontrar el problema del desbordamiento continuamente. Porque, en general, tu número binario lo vas a guardar en “alguna parte” de la memoria del ordenador (esa memoria tiene un tamaño, y si te pasas… 💥PUM, desbordamiento).
Por otro lado, el desbordamiento no es catastrófico “per se”. Es decir, no te va a explotar el ordenador, ni se va a romper nada. Simplemente el número que tuvieras almacenado volverá placita y silenciosamente a cero.
Claro que, si estabas usando ese número para contar algo… pues francamente, posiblemente bueno no sea (si era el nivel de tu jugador del WoW, volverás al principio. Si es un avión, quizás sea peor y se caiga al suelo).
Pero el desbordamiento no es malo. De hecho, es inevitable e incluso necesario en muchos procesos. Simplemente tienes que entenderlo, tenerlo en cuenta, y aprender a controlarlo.
Ejemplo de desbordamiento
Desbordamiento unsigned
Imaginemos que queremos guardar el número 300
en decimal, en un número binario. Pero, solo tenemos 8 bits.
El binario, el número 300
en decimal es 1 0010 1100
en binario. Necesitaríamos 9 dígitos para almacenarlo. Pero como solo tenemos 8 dígitos, lo máximo que podemos almacenar es 255 en decimal.
Por tanto, si vamos subiendo, desde 0 a 300, cuando lleguemos a 255 el contador se nos va a reiniciar en 0.
Vamos a verlo en pasos:
Paso | Binario | Decimal | Comentario |
---|---|---|---|
0 | 0000 0000 | 0 | Empezamos |
1 | 0000 0001 | 1 | |
2 | 0000 0010 | 2 | |
… | … | Sigo subiendo | |
255 | 1111 1111 | 255 | Llegamos al máximo |
256 | 0000 0000 | 1 | Desbordamos |
… | … | Sigo subiendo | |
300 | 0010 1100 | 44 |
El resultado almacenado será 0010 1100
en binario, que es 44 en decimal. Que es el mismo número que si hubieramos convertido a binario, y eliminado los bits que no caben (1 0010 1100
en este ejemplo, el 1
de la izquierda)
Desbordamiento signed
Si el número era signed (es decir, tiene signo) el problema es incluso peor. Siguiendo con el mismo ejemplo, supongamos que únicamente tenemos 8 bits. Pero ahora, al ser una variable signed, los límites son -128 a 127.
Si yo quiero guardar un número 300, no es solo que no quepa por un poco… ¡es que no cabe ni en dos veces 127!
Vamos a verlo también en pasos:
Paso | Binario | Decimal | Comentario |
---|---|---|---|
0 | 0000 0000 | 0 | Empezamos |
1 | 0000 0001 | 1 | |
2 | 0000 0010 | 2 | |
… | … | Sigo subiendo | |
127 | 0111 1111 | 127 | Máximo positivo |
128 | 1000 0000 | -128 | Pasamos a negativos |
129 | 1000 0001 | -127 | |
… | … | Sigo subiendo | |
255 | 1111 1111 | -1 | Máximo negativo |
256 | 0000 0000 | 0 | Desbordamos |
… | … | Sigo subiendo | |
300 | 0010 1100 | 44 |
Igual que en el caso de unsigned, hemos terminado con un número positivo 44
. Pero, por el camino, hemos pasado por todos los negativos de -128 a 0 (lo cuál, si no lo tenemos controlado, puede ser un auténtico problema).
Manejo del desbordamiento
Hemos dicho que lo más importante es entender el desbordamiento, y saberlo gestionar. En el desbordamiento influyen:
- La cantidad de bits que estamos gestionando (8, 16, 32, 64…)
- Si nuestra variable es signed o unsigned
En ambos casos, cuando vayamos añadiendo uno a nuestro número, el número binario se irá incrementando. Cuando llegue al límite de su capacidad, se reiniciará a cero.
Como hemos visto, es incluso más complicado si el número almacenado representa un número signed. Porque, el rango disponible será mucho más pequeño (la mitad menos uno), y además antes de desbordar, pasará por todo el rango de números negativos.
Para evitar el desbordamiento al almacenar números binarios en contenedores de longitud fija, tenemos que tener siempre en cuenta el rango de valores que se esperan manejar y elegir el tamaño de datos adecuado.
En entornos de programación, es común utilizar tipos de datos con tamaños específicos (como uint8, int16, etc.) que garantizan un rango válido de valores y nos ayudan a prevenir desbordamientos no deseados.
Además, al realizar operaciones aritméticas, es importante verificar los límites de los datos para evitar que un cálculo resulte en un valor fuera del rango permitido.