Otros sistemas de numeración¶
Ya hemos visto que, en la escritura de programas, podemos utilizar el sistema decimal o el binario:
x = 12345
x = 0b11000000111001
Los literales en sistema decimal es lo que podríamos considerar como escritura natural, pero no nos da visión sobre los bits en la memoria del ordenador. Pero el sistema binario es farragoso, con tantos ceros y unos.
En los inicios de la informática, los matemáticos descubrieron una tercera alternativa, el sistema de numeración octal.
El sistema octal¶
La ventaja del sistema de numeración octal está en el hecho de que las conversiones de octal a binario son fáciles de realizar.
En el sistema octal se cuenta de ocho en ocho, por lo que debemos limitarnos a ocho símbolos disponibles para representar números:
En decimal: 0 1 2 3 4 5 6 7 8 9
En octal: 0 1 2 3 4 5 6 7
Como sucede en el sistema decimal, para números más grandes, necesitamos combinar varios dígitos. Veamos la representación de los primeros números en decimal y su equivalente en octal:
| tabla_octal.py | |
|---|---|
1 2 3 4 | |
Lo que muestra:
decimal octal
------- -----
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 10
9 11
10 12
11 13
12 14
13 15
14 16
15 17
16 20
17 21
18 22
19 23
Al llegar al nº 8 se acaban los dígitos octales, y tenemos que comenzar a combinar números, pasando al 10. Y así sucesivamente. Al 47 le sucederá el 50, y al 77, el 100.
El especificador de formato para mostrar números en formato octal es una letra
o (mayúscula o minúscula) en lugar de una b:
print(f"{n:6} {n:5o}")
La ventaja de utilizar el sistema octal en la escritura de programas es que basta con sustituir cada dígito octal por tres dígitos binarios de acuerdo a la siguiente tabla:
| Binario | Octal |
|---|---|
| 000 | 0 |
| 001 | 1 |
| 010 | 2 |
| 011 | 3 |
| 100 | 4 |
| 101 | 5 |
| 110 | 6 |
| 111 | 7 |
Por ejemplo:
en decimal : 51966
en binario : 1 100 101 011 111 110
en octal : 1 4 5 3 7 6 = 145376
Por lo tanto, si en nuestro programa escribimos 145376 e indicamos de alguna forma que se trata de un número octal, será fácil convertir a binario sustituyendo cada dígito octal por sus tres dígitos binarios correspondientes.
En lenguaje Python, los literales octales se escriben anteponiendo un prefijo
0o o bien 0O (dígito cero y letra o, mayúscula o minúscula).
Las tres instrucciones siguientes son equivalentes:
x = 0b1100101011111110 (en binario)
x = 0o145376 (octal)
x = 51966 (decimal)
De todas formas, el uso del sistema octal en los programas está algo pasado de moda. Se usa más el sistema hexadecimal.
El sistema hexadecimal¶
El sistema octal tiene una pega: la memoria RAM está formada por bytes, que son paquetes de ocho bits, y lo ideal sería poder coger los dígitos binarios de cuatro en cuatro, en lugar de hacerlo de tres en tres.
Esto llevó en su momento a considerar el uso del sistema "hexadecimal" en la escritura de programas.
El sistema de numeración hexadecimal cuenta de 16 en 16. Al igual que hacíamos con los números romanos, utilizaremos letras para algunos símbolos:
decimal: 0 1 2 3 4 5 6 7 8 9
hexadecimal: 0 1 2 3 4 5 6 7 8 9 A B C D E F
Al escribir un programa se suele utilizar indistintamente mayúsculas o minúsculas. Veamos como se cuenta en decimal y en hexadecimal:
| tabla_hex.py | |
|---|---|
1 2 3 4 | |
Muestra:
decimal hexadecimal
------- -----------
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 A
11 B
12 C
13 D
14 E
15 F
16 10
17 11
18 12
19 13
20 14
21 15
22 16
23 17
24 18
25 19
26 1A
27 1B
28 1C
29 1D
30 1E
31 1F
32 20
33 21
34 22
35 23
36 24
37 25
38 26
39 27
Nótese que el especificador de formato para números hexadecimales es una
letra x (mayúscula o minúscula):
print(f"{n:6} {n:5X}")
En el ejemplo vemos que al llegar al número F se agotan las posibilidades
y pasamos al 10. Al llegar al 1F pasaremos al 20, y al llegar al FF,
el número siguiente será el 100.
Cuando escribimos un programa, lo habitual es escribir los números en decimal o en hexadecimal indistintamente. El uso de literales binarios u octales es más infrecuente, y se limita a situaciones puntuales.
Las conversiones de hexadecimal a binario son fáciles. Basta con tomar los bits de cuatro en cuatro y convertirlos de acuerdo a la siguiente tabla:
| Binario | Hexadecimal | Binario | Hexadecimal |
|---|---|---|---|
| 0000 | 0 | 1000 | 8 |
| 0001 | 1 | 1001 | 9 |
| 0010 | 2 | 1010 | A |
| 0011 | 3 | 1011 | B |
| 0100 | 4 | 1100 | C |
| 0101 | 5 | 1101 | D |
| 0110 | 6 | 1110 | E |
| 0111 | 7 | 1111 | F |
De esta forma, todo byte se puede representar con dos dígitos hexadecimales. Es decir:
- en binario, un byte toma valores de 00000000 a 11111111
- convirtiendo a decimal, de 0 a 255
- en octal, de 00 a 0377
- en hexadecimal, de 00 a FF
Cada paquete de cuatro bits se denomina nibble. Un byte está formado por dos nibbles, representado cada uno por un dígito hexadecimal.
El sistema hexadecimal resulta bastante práctico, una vez que nos acostumbramos
a su uso. En lenguaje Python, los literales hexadecimales se escriben
anteponiendo un prefijo 0x. Las cuatro instrucciones siguientes son
equivalentes, ya que representan el mismo valor:
x = 51966 (en decinal)
x = 0145376 (en octal)
x = 0b1100101011111110 (binario)
x = 0xCAFE (hexadecimal)
Cualquiera de las cuatro equivale el número binario 1100 1010 1111 1110,
pero si no queremos escribir tantos ceros y unos, el formato hexadecimal es el
que más se aproxima a la representación binaria.