Números¶
Datos numéricos¶
Supongamos que tenemos una base de datos con edades de un grupo de personas. Imaginemos una persona que tiene 35 años. Para saber como se representa este dato en forma de ceros y unos, basta con trasladar de sistema decimal a binario: 100011
.
La representación exacta depende del número de bits que ocupe el dato en la memoria del ordenador. Debemos rellenar el espacio con ceros por la izquierda. Para representar el valor 35, tenemos:
- Dato de 8 bits:
00100011
- Dato de 16 bits:
00000000 00100011
- Dato de 32 bits:
00000000 00000000 00000000 00100011
- Dato de 64 bits:
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00100011
Números negativos¶
En el sistema numérico binario no existen los números negativos. Para representarlos necesitamos de algún truco. Cada fabricante de chips tiene su diseño, pero lo más frecuente es que en cada dato se reserve un bit para indicar el signo.
Supongamos, por ejemplo, un dato que ocupa 32 bits, es decir, cuatro bytes. Dependiendo del diseño de la CPU, el primer dígito suele ser un 0 para valores positivos y un 1 para los negativos. De esta forma tendríamos:
cero: 00000000 00000000 00000000 00000000
uno: 00000000 00000000 00000000 00000001
valor máximo con 32 bits: 01111111 11111111 11111111 11111111
Convirtiendo de binario a decimal, el valor máximo de 32 bits será por lo tanto 2.147.483.647, considerando que el primer bit ha de ser un cero, por ser un valor positivo.
Se podría pensar que para representar cualquier número negativo basta con cambiar el primer bit, pero en realidad no suele ser así. Consideremos el número:
10000000 00000000 00000000 00000000
¿Que es esto? ¿Menos cero? Esto no funciona. Necesitamos otra forma de representar los valores negativos.
El diseño interno de los chips de un ordenador suele depender del fabricante, pero lo más frecuente es que funcionen como el cuentakilómetros de un coche. Al llegar a 999999
, pasa a mostrar 000000
. Si pudiésemos ir marcha atrás, al llegar a 000000
mostraría 999999
.
En un ordenador, si a una variable de 32 bits con valor cero le restamos uno, obtenemos:
cero: 00000000 00000000 00000000 00000000
menos uno: 11111111 11111111 11111111 11111111
y si seguimos restando, obtendríamos el mínimo valor posible, con todos los bits a cero, y el bit de signo a 1, por ser un valor negativo:
-2.147.483.648 = 10000000 00000000 00000000 00000000
Por lo tanto, para una variable de 32 bits tenemos:
valor máximo: 2.147.483.647 = 01111111 11111111 11111111 11111111
uno: = 00000000 00000000 00000000 00000001
cero: = 00000000 00000000 00000000 00000000
menos uno: = 11111111 11111111 11111111 11111111
valor mínimo: -2.147.483.648 = 10000000 00000000 00000000 00000000
Un detalle curioso. Si una variable de 32 bits puede representar datos dentro de un rango que va desde -2.147.483.648 hasta 2.147.483.647 ¿a que se debe esa asimetría? No existe el cero negativo, lo que deja espacio para un valor negativo extra.
En la práctica, los valores positivos son fáciles de interpretar. Basta con convertir de binario a decimal. Pero para interpretar un valor negativo, necesitamos una regla de cálculo. Entre los fabricantes de chips, el diseño más frecuente consiste en un sistema conocido como complemento a dos, que funciona de la siguiente forma:
-
Imaginemos una variable que ocupa ocho bits y su valor en binario es
0111 0011
. Vemos que el primer bit es 0, por lo que se trata de un número positivo. Basta con convertir de binario a decimal. Sumamos los pesos correspondientes a los unos, y obtenemos el valor de la variable: 64+32+16+2+1 = 115 -
Ahora bien, supongamos que cambiamos el primer bit. Ahora es
1111 0011
, y se trata de un número negativo, pero no lo podemos interpretar como -115. Vamos a seguir la regla del complemento a dos. -
En primer lugar, invertimos los bits, con lo que tenemos
0000 1100
. A esto se le llama “complemento a uno“. -
Le sumamos 1, lo que resulta
00001101
-
Lo convertimos al sistema decimal, obteniendo un valor 13
-
Le añadimos el signo: -13
Por lo tanto, 0111 0011
en un dato de ocho bits cuyo valor equivale a 115, y si ponemos a 1 el bit de signo, 1111 0011
equivale a -13.
¿Por que a esta técnica se le llama complemento a dos? Porque se realiza un complemento a 1 y se le suma 1.
Números sin signo¶
Supongamos un dato que ocupa ocho bits y su valor en binario es 1111 1111
. Cuando escribamos un programa tenemos que decidir como interpretarlo.
Podríamos pensar que se trata de un valor numérico con signo. Aplicando la regla del complemento a dos, el valor representado es -1.
Pero también podríamos considerar que se trata de un dato sin signo, es decir, que el primer bit forma parte de la cantidad representada. Convirtiendo de binario a decimal, el valor será 255.
La interpretación del dato es responsabilidad del programador. El ordenador se limita
a almacenar una secuencia de dígitos binarios. Nosotros podemos interpretar 1111 1111
como -1 o como
255. Cuando en nuestro programa establezcamos que el primer bit representa el signo,
diremos que tenemos un dato “con signo”, signed, y si decidimos lo contrario,
tendremos un valor unsigned. Eso forma parte de las instrucciones del programa.
Ya hemos visto el posible rango de valores que pueden tomar los números sin signo:
- con 8 bits, los valores pueden ir de 0 a 255
- con 16 bits, los valores pueden ir de 0 a 65.535
- con 32 bits, los valores pueden ir de 0 a 4.294.967.295
- con 64 bits, los valores pueden ir de 0 a 18.446.744.073.709.551.615
Véase que el valor mínimo de un número sin signo siempre es cero. Pero si el dato es con signo, el rango de posibles valores puede ser:
- con 8 bits: de -128 a 127
- con 16 bits: de -32.768 a 32.767
- con 32 bits: de -2.147.483.648 a 2.147.483.647
- con 64 bits: de −9.223.372.036.854.775.807, a 9.223.372.036.854.775.807