|
|
||
| PRIMERO DE INGENIEROS INDUSTRIALES | ||
| UNIVERSIDAD POLITÉCNICA DE CARTAGENA |
FUNDAMENTOS DE INFORMÁTICA. PROGRAMACIÓN EN C. |
|
|
Pedro María Alcover Garau |
PRIMERO DE INGENIEROS TÉCNICOS INDUSTRIALES |
|
|
0.
Presentación. |
CODIFICACIÓN INTERNA DE LA INFORMACIÓN
La información, en un ordenador, se almacena mediante datos codificados con ceros y unos. Ya lo hemos visto en los capítulos precedentes. Ahora, en este capítulo, queremos ver cómo son esos códigos de ceros y unos. No nos vamos a entretener en la codificación de todos los posibles tipos de dato. Hemos centrado principalmente la presentación de este capítulo en el modo como se codifican los enteros. Y eso por dos motivos: porque es un código muy sencillo; y porque resulta de gran utilidad, en el lenguaje C, conocer esa codificación: el lenguaje C ofrece herramientas para poder manipular ese código y obtener, si se sabe, resultados interesantes y ventajosos. Al tratar de los datos a codificar, deberemos distinguir entre la codificación que se emplea para la entrada y salida de datos, y la que el ordenador usa para su almacenamiento en memoria. Por ejemplo, si el usuario desea introducir el valor 412, deberá pulsar primero el cuatro, posteriormente la tecla del uno, y finalmente la del dos. El modo en que el teclado codifica e informa a la CPU de la introducción de cada uno de estos tres caracteres será diferente al modo en que finalmente el ordenador guardará en memoria el valor numérico 412. Así las cosas, el modo en que un usuario puede suministrar información por teclado a la máquina es mediante caracteres, uno detrás de otro. Estos caracteres podemos clasificarlos en distintos grupos: 1. de Texto: a. Alfanuméricos: i. Alfabéticos: de la ‘a’ a la ‘z’ y de la ‘A’ a la ‘Z’. ii. Numéricos: del ‘0’ al ‘9’. b. Especiales: por ejemplo, ‘(‘, ‘)’. ‘+’. ‘?’. ‘@’,… 2. De control: por ejemplo, fin de línea, tabulador, avance de página, etc. 3. Gráficos: por ejemplo, ‘☺’, ‘♥’, ‘♣’,… Como el ordenador sólo dispone, para codificar la información, de ceros y de unos, deberemos establecer una correspondencia definida entre el conjunto de todos los caracteres y un conjunto formado por todas las posibles secuencias de ceros y de unos de una determinada longitud. A esa correspondencia la llamamos código de Entrada/Salida. Existen muchos distintos códigos de E/S, algunos de ellos normalizados y reconocidos en la comunidad internacional. Desde luego, cualquiera de estas codificaciones de E/S son arbitrarias, asignando a cada carácter codificado, una secuencia de bits, sin ninguna lógica intrínseca. Estos códigos requieren de la existencia de tablas de equivalencia uno a uno, entre el carácter codificado y el código asignado para ese carácter. Y, como acabamos de decir, esta codificación es distinta de la que, una vez introducido el dato, empleará el ordenador para codificar y almacenar en su memoria el valor introducido. Especialmente, si ese valor es un valor numérico. En ese caso especialmente, tiene poco sentido almacenar la información como una cadena de caracteres, todos ellos numéricos, y resulta mucho más conveniente, de cara también a posibles operaciones aritméticas, almacenar ese valor con una codificación numérica binaria. En ese caso, estamos hablando de la representación o codificación interna de los números, donde ya no se sigue un criterio arbitrario o aleatorio, sino que se toman en consideración reglas basadas en los sistemas de numeración posicional en base dos.
Códigos de Entrada/Salida. Ya hemos quedado que esta codificación es arbitraria, asignando a cada carácter del teclado una combinación de una longitud determinada de bits. La cantidad de bits necesaria para codificar todos los caracteres dependerá, lógicamente, del número de caracteres que se deseen codificar. Por ejemplo, con un bit, tan solo se pueden codificar dos caracteres: a uno le correspondería el código 0 y al otro el código 1. No tenemos más valores de código posibles y, por tanto, no podemos codificar un conjunto mayor de caracteres. Con dos bits, podríamos codificar cuatro caracteres; tantos como combinaciones posibles hay con esos dos dígitos binarios: 00, 01, 10 y 11.
En general diremos
que con Una vez decidido el cardinal del conjunto de caracteres que se desea codificar, y tomado por tanto como longitud del código el menor número de bits necesarios para lograr asignar un valor de código a cada carácter, el resto del trabajo de creación del código será asignar a cada carácter codificado una secuencia de ceros y unos, de longitud la longitud del código; secuencia que deberá ser diferente a cualquiera otra que se haya ya empleado para codificar otro carácter.
Desde luego, se hace
necesario lograr universalizar los códigos, y que el mayor números de
máquinas trabaje con la misma codificación, para lograr un mínimo de
entendimiento entre ellas. Para eso surgen los códigos normalizados de
ámbito internacional. De entre los diferentes códigos normalizados
válidos, señalamos aquí el Código ASCII (American Standard Code for
Information Interchange). Es el código más ampliamente utilizado. Está
definido para una longitud de código En el código ASCII el carácter ‘A’ tiene el valor decimal 65 (en hexadecimal 41), y consecutivamente, hasta el carácter ‘Z’ (valor decimal 90, en hexadecimal 5A), van ordenados alfabéticamente, todas las letras mayúsculas. El alfabeto en minúsculas comienza un poco más adelante, con el código decimal 97 (61 en hexadecimal) para la ‘a’ minúscula. Los caracteres numéricos comienzan con el valor decimal 48 (30 en hexadecimal) para el carácter ‘0’, y luego, consecutivos, están codificados los restantes nueve guarismos de la base diez.
Representación o Codificación Interna de la Información. La codificación de Entrada/Salida no es útil para realizar operaciones aritméticas. En ese caso resulta mucho más conveniente que los valores numéricos queden almacenados en su valor codificado en base dos. Por ejemplo, utilizando el código ASCII, el valor numérico 491 queda codificado como 0110100 0111001 0110001. Ese mismo valor, almacenado con 16 bits, en su valor numérico, toma el código 0000000111101011. No resulta mejor código únicamente porque requiere menos dígitos (se adquiere mayor compactación), sino también porque esa codificación tiene una significación inmediatamente relacionada con el valor codificado. Y porque un valor así codificado es más fácilmente operable desde la ALU que si lo tomamos como una secuencia de caracteres de código arbitrario. Es decir, se logra una mayor adecuación con la aritmética. Vamos a ver aquí la forma en que un ordenador codifica los valores numéricos enteros, con signo o sin signo. Desde luego, existe también una definición y normativa para la codificación de valores numéricos con decimales, también llamados de coma flotante (por ejemplo, la normativa IEEE 754), pero no nos vamos a detener en ella.
Enteros sin signo Para un entero sin signo, el sistema utilizado es tomar como código su valor en base binaria. Sin más.
Por ejemplo, para
codificar el valor numérico Además de saber cómo se codifica el entero, será necesario conocer el rango de valores codificables. Y eso estará en función del número de bits que se emplearán para la codificación. Si tomáramos un byte para codificar valores enteros sin signo, entonces podríamos codificar hasta un total de 256 valores. Tal y como se ha definido el código en este epígrafe, es inmediato ver que los valores codificados son los comprendidos entre el 0 (código 00000000) y el 255 (código 11111111), ambos incluidos. Si tomáramos dos bytes para codificar (16 bits), el rango de valores codificados iría desde el valor 0 hasta el valor 65.535 (en hexadecimal FFFF). Y si tomáramos cuatro bytes (32 bits) el valor máximo posible a codificar sería, en hexadecimal, el FFFFFFFF que, en base 10 es el número 4.294.967.295.
Evidentemente,
cuantos más bytes se empleen, mayor cantidad de enteros se podrán
codificar y más alto será el valor numérico codificado. En general, el
rango de valores codificados con
Enteros con signo Hay diversas formas de codificar un valor numérico con signo. Vamos a ver aquí una de ellas, la que se emplea en los PC’s de uso habitual. El modo de codificar enteros con signo es el siguiente: 1. El bit más significativo no es un dígito numérico, sino el signo. Se pone a 0 si el entero codificado es positivo; se pone a 1 si el entero codificado es negativo. 2. Los restantes bits se emplean para la codificación del valor numérico. Si el entero es positivo, se codifica en esos bits ese valor numérico en base binaria. Si el entero es negativo, entonces lo que se codifica en esos bits es el complemento a la base del valor absoluto del valor codificado. Si queremos saber entonces cómo queda codificado, con un byte, el valor numérico -75, debemos hacer los siguientes cálculos: El bit más significativo será 1, porque el entero a codificar es negativo. El código binario del valor absoluto del número es 1001011 (siete dígitos, que son los que nos quedan disponibles). El complemento a la base menos uno de ese valor es 0110100 (se calcula invirtiendo todos los dígitos: de 0 a 1 y de 1 a 0), y el complemento a la base será entonces 0110101 (recuérdese la igualdad 2.6.). Por tanto la representación interna de ese valor será 10110101, que en base hexadecimal queda B5. Si hubiésemos codificado el entero con dos bytes entonces el resultado final del código sería FFB5. El rango de valores codificados cambia con respecto al presentado antes con los enteros sin signo, pero la cantidad de valores codificados es la misma en el caso de enteros con signo y enteros sin signo. Ahora el rango de valores queda centrado en el cero: toma la mitad de los códigos para valores negativos y la otra mitad para valores positivos más el cero. Por ejemplo, con un byte se codifican los enteros comprendidos entre -128 y +127. Con dos bytes se pueden codificar los enteros comprendidos entre -32.768 y + 32.767. Y con cuatro bytes el rango de valores codificados va desde el -2.147.483.648 hasta el +2.147.483.647.
En general, el rango
de valores codificados con
Ejercicios El mejor modo para llegar a manejar la técnica de codificación de los enteros es la práctica. Quedan recogidos, en este último epígrafe, la codificación de diferentes valores numéricos, para que se pueda practicar y verificar los resultados obtenidos. Todos ellos son valores negativos, y todos ellos codificados con dos bytes (16 bits, 4 dígitos hexadecimales).
|