1.4.1. Representación de la información¶
Toda la información que almacena y lee un ordenador la maneja en código binario, esto es, como una sucesión de ceros y unos. Esto supone que el sistema binario es la base predominante en informática. Se tratará bajo este epígrafe:
Cómo representar números en distintos sistemas de numeración.
Cómo códificar caracteres alfanuméricos en código binario.
1.4.1.1. Sistemas de numeración¶
Un sistema de numeración es un conjunto de reglas y símbolos que permite representar todos los números válidos. Los modernos sistemas de numeración son posicionales, en los cuales el valor del símbolo dependen de la posición que ocupa. Por ejemplo, en el número decimal 11, el primero 1 representa 1 decena (o sea, su valor es 10 unidades), mientras que el segundo 1 tiene por valor 1 unidad.
Por base se entiende la cantidad de símbolos distintos usandos para representar los números. El sistema que habitualmente utilizamos es el sistema decimal o en base 10 en que los 10 símbolos son 0, 1, 2, 3, 4, 5, 6, 7, 8 y 9.
De nuestro interés son:
Nombre |
Base |
Símbolos |
Razón de su interés |
---|---|---|---|
Binario |
2 |
0 y 1 |
Es el que internamente usan los ordenadores para representar la información. |
Octal |
8 |
0-7 |
Es muy sencilla su conversión a binario y viceversa, y la representación es más compacta. |
Decimal |
10 |
0-9 |
Es el usado habitualmente por el ser humano. |
Hexadecimal |
16 |
0-9, A-F |
Es muy sencilla su conversión a binario y viceversa, y la representación es más compacta. |
En estos sistemas de numeración los números se representan de este modo.
Decimal |
Binario |
Octal |
Hexadecimal |
---|---|---|---|
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
2 |
10 |
2 |
2 |
3 |
11 |
3 |
3 |
4 |
100 |
4 |
4 |
5 |
101 |
5 |
5 |
6 |
110 |
6 |
6 |
7 |
111 |
7 |
7 |
8 |
1000 |
10 |
8 |
9 |
1001 |
11 |
9 |
10 |
1010 |
12 |
A |
11 |
1011 |
13 |
B |
12 |
1100 |
14 |
C |
13 |
1101 |
15 |
D |
14 |
1110 |
16 |
E |
15 |
1111 |
17 |
F |
16 |
10000 |
20 |
10 |
17 |
10001 |
21 |
11 |
18 |
10010 |
22 |
12 |
19 |
10011 |
23 |
13 |
20 |
10100 |
24 |
14 |
Fundamentalmente, el interés sobre estos métodos radica en:
Saber cómo convertir números entre los sistemas binario y decimal.
Saber cómo convertir entre octal o hexadecimal y binario, ya que los dos primeros sistemas se suelen usar para escribir de una forma más compacta cifras binarias.
Nota
En textos sin formato en los que no pueden usarse subíndices para notar cuál es la base en la que está expresado un número (p.e. expresar un hexadecimal con la forma \(\mathit{C1A}_{16)}\)), es común usar esta notación:
Binario: Antecediendo el número con
0b
:0b11011
.Octal: Antecediendo el número con un cero:
0745
.Decimal: Se escribe de forma normal.
Hexadecimal: Antecediendo el número con
0x
:0xC1A
.
1.4.1.1.1. Método general de conversión a decimal¶
1.4.1.1.2. Cuenta de la vieja (entre binario y decimal)¶
1.4.1.1.3. Conversión entre octal y binario¶
1.4.1.1.4. Conversión entre hexadecimal y binario¶
1.4.1.1.5. Ejercicios sobre sistemas de numeración¶
Escriba los veinte números que suceden a:
N
101100012)
17638)
BFF216)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Haga otro tanto con:
N
11111002)
6658)
6E516)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Lleve a cabo la conversión entre los cuatro sistemas de numeración
Binario
Octal
Decimal
Hexadecimal
11011101
123
F2
333
11111001
564
10F
553
671
250
D2
101001110
1.4.1.2. Tipos de datos¶
Todos la información la almacena el ordenador en forma de ceros y unos. Sin embargo, los datos son de distinta naturaleza, esto es, de distinto tipo, y, en consecuencia, deben existir distintos mecanismos para transformar la información almacenada (exclusivamente) en forma binaria. Los datos, fundamentalmente, son:
Números enteros.
Números reales.
Caracteres.
También hemos de tener presente que, cuando pensamos representar un tipo de dato, debemos prefijar con cuántos bytes deseamos expresarlo. Por ejemplo, podríamos decidir que, para representar/almacenar números enteros, utilizaremos 2 bytes. Sin ser muy exhaustivos, esta podría ser una tabla resumen:
Tipo |
Tamaño (bytes) |
---|---|
Carácter |
1 |
Entero corto |
2 |
Entero |
4 |
Entero largo |
8 |
Real (simple) |
8 |
Real (doble) |
16 |
Obviamente, cuanto mayor sea el tamaño que dediquemos a codificar el dato, mayor será el rango de números (o caracteres) que podamos almacenar.
Nota
La tabla admite muchísimas puntualizaciones. Ya veremos, por ejemplo, que la estrategia moderna de codificar caracteres es usar un tamaño varible.
1.4.1.2.1. Representación de números enteros¶
Si no existieran los número negativos, sería sumamente simple: bastaría con
escribir la expresión binaria del número tal como la hemos estudiando
anteriormente y ya está. Por ejemplo, si ocupásemos un byte para codificar el
número 123, se almacenaría como 01111011
. Sin embargo, existen los
negativos, por lo que hay que decidir estrategias para representarlos. Las
principales son cuatro, aunque modernamente se usa la tercera:
- Bit para el signo
Es la más sencilla de entender. Simplemente, se reserva un bit para representar el signo: 0 para el positivo y 1 para el negativo, lo cual nos dejaría 7 bits (supuestos los 8 que hemos decidido que usaremos para codificar) para representar la magnitud, que la representamos simplemente haciendo las conversiones antes vistas. De este modo:
Número
Representacion
123
01111011
-123
11111011
El problema de esta representación es que las operaciones de suma y resta no pueden tratarse del mismo modo y que, además, hay dos maneras de representar el 0.
- Complemento a uno
Consiste en reservar el primer bit que será siempre 0 para números positivos y representar la magnitud con los restantes del modo ya visto al tratar las conversiones entre bases. Por tanto, la representación de números naturales es exactamente la vista para el caso anterior. Los números negativos son el complementario de su correspondiente positivo, esto es, el que se obtiene cambiando bit a bit 0 por 1 y 1 por 0:
Número
Representacion
123
01111011
-123
10000100
Esta estrategia presenta la ventaja de que sumas y restas pueden reducirse a una misma operación: \(50-8\) puede reducirse a la suma \(50+(-8)\). También el 0 tiene dos representaciones (00000000 y 11111111).
Nota
En realidad, hay que tener una pequeña prevención al restar. La operación anterior (50-8) es la suma binaria \(00110010 + 11110111\) que es 100101001, número que ocupa 9 cifras. Eso es, en realidad, un acarreo, porque representamos los números con 8 cifras. El 1 del acarreo hay que sumarlo a las 8 cifras para obtener el resultado: \(00101001 + 1 = 00101010\), que es justamente 42.
- Complemento a dos
Semejante al complemento a uno con la diferencia de que los números negativos se obtienen de sumar 1 a la representanción del número negativo en complemento a uno. Por tanto:
Número
Representacion
123
01111011
-123
10000101
Con esta representación no es necesario reintroducir el acarreo para restar y, además, no hay más que una forma de representar el 0.
- Exceso a X
Consiste en representar todo como números positivos y establecer el 0 no en
00000000
, sino en la cifra binaria intermedia que deje un intervalo simétrico de números positivos y negativos. Así, si representamos con 8 bits los números binarios van del00000000
al11111111
, lo que en principio sería del 0 al 255. Pero no, decidimos que vamos de -127 a 128 con lo que00000000
representa el -127 y11111111
, el 128. En este caso, usamos el exceso a 127 y el 0 estaría representado por el binario01111111
(\(127 - 127 = 0\)).
1.4.1.2.2. Representación de números reales¶
Los números con decimales estamos acostumbrados a representarlos con una parte entera y una parte decimal (llamada mantisa) separadas ambas por una coma (o un punto). Por ello, escribimos 1.234, 45.678 o -56783.3456. Del mismo modo que creamos números con decimales en base 10, podríamos crear números binaros con decimales. Por ejemplo, \(1101.101_2\) representa el número decimal \(1*2^3+1*2^2+0*2^1+1*2^0+1*2^{-1}+0*2^{-2}+1*2^{-3} = 13.625\).
Sin embargo, esta representación habitual es poco apropiada porque, dado que deberemos escoger un tamaño para almacenar los números (por ejemplo, 32 bits), si queremos poder representar números muy grandes (la parte entera será grande), entonces tendremos que acortar la precisión que proporciona la mantisa; y viceversa. Por este motivo, en informática se utiliza la notación de coma flotante.
La notación de coma flotante consiste en adjuntar a la expresión del número una potencia de diez que exprese su magnitud. Por ejemplo, -56783.3456 podríamos expresarlo como \(-56.783456*10^3\). Si, además, indicamos la potencia de diez de suerte que la parte entera sólo tenga una cifra, entonces la notación esta normalizada. De este modo los ejemplos anteriores en esta notación normalizada se expresarían como \(1.234*10^0\), \(4.5678*10^1\) y \(-5.67833456*10^4\). Como todas las cantidades están expresadas en base decimal, la base del exponente siempre será diez, por lo que estas cantidades tienes tres variables:
El signo. Como hay dos posibilidades, podemos notar al «+» con 0 y al «-» con 1.
El significado, esto es, el número significativo. La coma siempre está en la misma posición, así que podríamos prescindir de usarla.
El exponente.
Por tanto, un numero real lo podemos expresar como la combinación de tres reales: signo, mantisa y exponente:
Número |
Signo |
Exponente |
Significado |
---|---|---|---|
1.234 |
0 |
0 |
1234 |
45.678 |
0 |
1 |
45678 |
-56783.3456 |
1 |
4 |
567833456 |
Esta es, conceptualmente, la explicación de la notación de coma flotante. Sin embargo, los ordenadores sólo utilizan el sistema binario para representanción, así que debemos repensar todo esto en ese sistema. Partamos de nuestro ejemplo 13.625, cuya representación binaria es \(1101.101_2\). o, lo que es lo mismo, \(1.101101*2^3\). Pero, ¿qué hacen ese 2 y ese 3 en esa representación binaria? Del 2 directamente podemos prescindir como prescindimos cuando pensábamos en decimal del 10. El 3 forzosamente sí habrá que pasarlo a binario (\(11_2\)). Por tanto:
Número |
Signo |
Exponente |
Significado |
---|---|---|---|
1101.101 |
0 |
11 |
1101101 |
Esto es una primera aproximación, pero los ordenadores no pueden crear tablitas como nosotros para representar un número: simplemente reservan una cantidad de bits y escriben en ellos ceros o unos. Lo que se hace, para evitar problemas es reservar una cantidad fija de bits para cada componente. La cantidad para el signo es evidente: 1 y para los otros dos componentes de la notación depende de la cantidad de bits que usemos:
Tipo |
Signo |
Exponente |
Mantisa |
Total |
---|---|---|---|---|
Coma flotante simple |
1 |
8 |
23 |
32 |
Coma flotante de doble precisión |
1 |
11 |
52 |
64 |
Nota
La columna para expresar el tamaño del «significado» se ha nombrado como «mantisa» (o sea, sólo la parte decimal). Más adelante veremos por qué.
Por tanto, si usamos el tipo simple, una mejor aproximación a cómo notan estos números los ordenadores es:
Número |
Signo |
Exponente |
Significado |
---|---|---|---|
1101.101 |
0 |
00000011 |
11011010000000000000000 |
Obsérvese que hemos añadido al significado los ceros a la derecha y no a la izquierda como comúnmente se hace. Esto se debe a que el punto decimal siempre estará entre el primer bit y el segundo, por lo que los ceros a la derecha, en realidad. son ceros de relleno. Por otro lado, la notación siempre está normalizada, por lo que el primer dígito de la mantisa si usamos binario siempre será 1. Por tanto, ¿para qué escribirlo y perder un bit? En consecuencia, se prescinde del 1 que tiene la parte entera y sólo se escribe la parte decimal, esto es, la mantisa. La representación quedaría finalmente así:
Número |
Signo |
Exponente |
Mantisa |
---|---|---|---|
1101.101 |
0 |
00000011 |
10110100000000000000000 |
Yuxtaponiendo las tres partes para constituir el dato de 32 bits, tenemos la
representación que hace del número el ordenador:
00000001110110100000000000000000
. Hemos soslayado una cuestión para
hacer más simples las explicaciones: ¿qué ocurre cuando el exponente es
negativo (p.e. el número 0.0011011)? No hay bit para el signo del exponente:
se usa el complemento a dos.
Por último, deben tenerse presente algunas particularidades:
El exponente define la magnitud del número (cuanto mayor, más grande).
La mantisa define la precisión del numero (cuanto mayor, más preciso).
La regla general es que la notación siempre es normalizada y, además, sólo se expresa la mantisa. Esto, sin embargo, haría imposible representar el 0, ya que la parte entera siempre se sobrentiende 1. Por ese motivo, hay dos excepciones:
Cuando el exponente tiene todos sus bits a 0, no se sobrentiende parte entera y la mantisa representa en realidad al significado. Por tanto, todos los bits a 0 de signo, exponente y mantisa significan \(+0\) y lo mismo pero con el bit del signo a 1, \(-0\).
Cuando el exponente tiene todos sus bits a 1:
y la mantisa es 0, se entiende \(+\infty\) o \(-\infty\) dependiendo del bit de signo.
y la mantisa no es 0, se entiende NaN.
1.4.1.2.3. Representación de caracteres¶
Además de la representación numérica, en los ordenadores es necesario también representar caracteres alfanuméricos, esto es, letras, números, símbolos de puntuación o símbolos de control (p.e. un cambio de línea). Como la información siempre debe tratarse en binario, para llevarlo a cabo se definen tablas de codificación que relacionan cada símbolo con el código binario que lo representa.
Un sistema de codificación es un sistema normalizado que permite codificar en formato binario un determinado conjunto de caracteres. Hay distintos sistemas de codificación:
- De ancho fijo
Son sistemas de codificación en los que los códigos binarios tienen todos la misma longitud, esto es, el mismo número de cifras binarias.
- ASCII
Es una sistema de codificación de ancho de 7 bits capaz de representar caracteres de control (los 32 primeros códigos y el último), de puntuación y letras del alfabeto inglés. Su importancia radica en que la mayoría de los sistemas de codificación son compatibles con él.
Ver también
Consulte la tabla de codificación ASCII
Como la información suele agruparse en grupos de 8 bits (1 byte), hay toda una serie de sistemas de codificación de ancho fijo de 8 bits, cuyos primeros 128 caracteres coinciden con la codificación ASCII. A estos sistemas de codificación suele denominárseles ASCII extendido.
- ASCII extendido
Forma genérica de denominar a un conjunto dispar de sistemas de codificación de 8 bits cuyos primeros 128 códigos coinciden con el ASCII estándar y, por tanto, son compatibles con el ASCII original de 7 bits. Los más comunes son:
- CP 437
Sistema de codificación de 8 bits que extiende ASCII y cuyos 128 códigos superiores se dedican a caracteres para el diseño de tablas, símbolos matemáticos, algunas letras griegas (usadas en matemáticas y física) y algunas vocales acentuadas que existen en las lenguas de Europa occidental, pero insuficientes para escribir correctamente en estas lenguas. Era el usado en las primeros version de inglesas de MS-DOS.
- CP 850
Semejante al anterior, pero sustituye algunos caracteres para el dibujo de tablas y letras griegas por los caracteres que faltan para lograr escribir completamente en las lenguas de Europa occidental. Se usaba en las versiones europeas de MS-DOS.
- Sistemas ISO/IEX 8859
Conjunto de 15 sistemas de ASCII extendido cada uno de los cuales orientado a escribir un conjunto distinto de lenguas. El ISO-8859-1 es el encargado de codificar los caracteres necesarios para escribir en las lenguas europeas occidentales; y el ISO-8859-15 es una modificación de este para codificar el símbolo del euro y algunas pocas letras acentuadas.
- CP 1252 Windows-1252
SIstema de codificación de ASCII extendido usado en sistemas Windows hasta época más o menos reciente, muy semejante a ISO-8859-1, del cual difería en unos pocos caracteres de control.
- UTF-32
Sistema de códificación de ancho fijo de 32 bits que es capaz de codificar los símbolos necesarios para escribir en todas las lenguas más algunos otros símbolos matemáticos, musicales, etc. Pese a esa ventaja, presenta dos desventajas:
Como cualquier carácter se representa con 4 bytes, aumenta considerablemente el tamaño para almacenar cualquier fichero de caracteres, aunque este sólo incluya caracteres muy simples.
Es incompatible con ASCII.
- De ancho variable
Al contrario de los anteriores, todos sus códigos binarios no tienen la misma longitud. Los dos sistemas de codificación de ancho variables más usados son:
- UTF-16
Sistema de codificación de ancho variable que usa 2 ó 4 bytes para codificar todos los caracteres existentes. Para optimizar el tamaño, los caracteres que usan códigos de 2 bytes son los que permiten escribir en las lenguas de mayor uso. Tiene el inconveniente de que es incompatible con ASCII.
- UTF-8
Sistema de codificación de ancho variable que usa códigos de 1, 2, 3 ó 4 bytes para representar todos los caracteres existentes:
Codifica con 1 bytes los carácteres ASCII usando los mismos códigos, con lo que logra compatibilidad con este sistema de codificación.
Codifica con 2 bytes caracteres para escribir en las lenguas europeas, el árabe o el hebreo.
Códifica con 3 bytes caracteres no linguísticos de uso común y lenguas como el chino o el japonés.
Códifica con 4 bytes en resto de caracteres unicode.
Dado que optimiza el tamaño, es compatible con ASCII y permite codificar cualquier carácter unicode es el sistema de codificación que usan los sistemas operativos modernos. Como contrapartida, ofrece el peor rendimiento al ser computado.