Sistemas de numeración

Generalidades

Números

En programación es frecuente acudir a diferentes sistemas de numeración según las circunstancias.

Hay que tener en cuenta que el hombre usa el sistema decimal, (según una opinión bastante general debido a una circunstancia más o menos afortunada: por la simple razón de que tiene diez dedos entre las dos manos. A menudo se usa el cinco como base de numeración auxiliar). La palabra dígito y dedo tienen la misma raíz latina, por eso usamos una numeración con 10 dígitos o dedos.

Hubiera sido mucho más práctico usar un sistema de numeración basado en un número con más factores, como el 12 (3*2*2) o mejor todavía el 8 (2*2*2) o el 16 (2*2*2*2). Pero por suerte o por desgracia:

  1. Los humanos tenemos diez dedos y
  2. Los humanos contamos con los dedos (al menos al principio), porque están muy a mano.

Para contar de 1 a 10 es fácil, pero ¿qué pasa cuando hay que contar más de diez cosas?. Pues usamos las manos de un "amigo" para contar cuantas veces hemos usado los dedos de las nuestras, así "12", sería dos más una vez diez.

Otra circunstancia curiosa es que en el sistema de numeración que usamos los números se leen y escriben de derecha a izquierda, al revés del modo en que escribimos las palabras.

Cuando interpretamos números de varias cifras, hay que empezar por la derecha, el primer dígito son unidades, el siguiente decenas, es decir cuantos grupos de 10 elementos estamos contando. El siguiente centenas, es decir el número de grupos de 10 elementos de grupos de 10 elementos, o sea el número de grupos de 100 elementos. Y así sucesivamente.

Si quieres saber más detalles sobre la historia de los sistemas de numeración, consulta este enlace.

Sistemas de numeración en la programación

En C y C++ se usan básicamente cuatro sistemas de numeración:

  • Binario (base 2)
  • Octal (base 8)
  • Decimal (base 10)
  • Hexadecimal (base 16)

Sistema binario, numeración en base 2

El sistema binario es el que usan los ordenadores, que es como si sólo tuvieran un dedo, su unidad básica de memoria, el bit, sólo puede tomar dos valores, inactivo o activo, y se codifican como 0 y 1, respectivamente.

Los ordenadores se quedan sin dedos enseguida, en cuanto tienen que contar más de uno, así que añaden más dígitos.

Por ejemplo, veamos el número binario 10110.

Estamos en base 2, así que el número se calcula así:

0 * 20 + 1 * 21 + 1 * 22 + 0 * 23 + 1 * 24 = 2 + 4 + 16 = 22 (decimal)

Este tipo de numeración resulta muy útil cuando cada bit puede significar cosas diferentes para un ordenador.

Sistema octal, numeración en base 8

El sistema octal usa ocho dígitos: 0, 1, 2, 3, 4, 5, 6 y 7. Este es el sistema de numeración que usaríamos si tuviéramos manos de cuatro dedos, como los Simpsons :-)

Por ejemplo, un número en octal sería 125. Estamos en base 8,así que el número se traduce a decimal así:

5 * 80 + 2 * 81 + 1 * 82 = 5 + 2 * 8 + 64 = 85 (decimal)

Desconozco el origen histórico de por qué de usa este sistema de numeración en ordenadores. Pero la explicación práctica es que la conversión entre binario y octal es casi directa.

Por ejemplo tenemos el número binario 10010010001000101101001.

Para convertirlo a octal agrupamos los dígitos de tres en tres empezando por la derecha, y rellenamos con ceros a la izquierda hasta tener sólo grupos de tres bits o dígitos:

010 | 010 | 010 | 001 | 000 | 101 | 101 | 001

A cada grupo de tres bits le podemos hacer corresponder un dígito octal, al 000 el 0, al 001 el 1, al 010 el 2, ... al 111 el 7.

Así que podemos traducir directamente el número anterior a octal:

22210551 (octal)

La conversión inversa, de octal a binario es igual de simple. Por ejemplo el número octal:

125

Cambiamos cada dígito octal por su equivalente binario:

001 | 010 | 101

Y después eliminamos los separadores y los ceros iniciales:

1010101 (binario)

Sistema decimal, numeración en base 10

En programación se usa el decimal porque es el que usamos los humanos, y al fin y al cabo, el ordenador está a su servicio.

Es sistema decimal usa diez dígitos para expresar los números, 0, 1, 2, 3, 4, 5, 6, 7, 8 y 9.

Por ejemplo para el número decimal 42335:

5 * 100 + 3 * 101 + 3 * 102 + 2 * 103 + 4 * 104 = 5 + 30 + 300 + 2000 + 40000

Sistema hexadecimal, numeración en base 16

El sistema hexadecimal, que es el rey de los sistemas de numeración, al menos en lo que respecta a los ordenadores.

Usa 16 dígitos, los archiconocidos 0 a 9 y para los otros seis se usan las letras A, B, C, D, E y F, que tienen valores 10, 11, 12, 13, 14 y 15, respectivamente. Se usan indistintamente mayúsculas y minúsculas.

Por ejemplo, un número hexadecimal 4F3D:

13 * 160 + 3 * 161 + 15 * 162 + 4 * 163 = 13 + 3 * 16+ 15 * 256 + 4 * 4096 = 20285

Este sistema de numeración tiene muchas ventajas:

  • La conversión entre binario y hexadecimal es tan simple como en octal, la única diferencia es que los bits se agrupan de cuatro en cuatro. 0000 es 0, 0001 es 1, 0010 es 2 ... 1111 es F.
  • El byte, es la unidad de memoria más usada por los ordenadores y agrupa ocho bits. Para codificar un número de 8 bits sólo se necesitan dos dígitos hexadecimales. El mayor número expresable por un byte, 11111111(binario), equivale a 255(decimal) y a FF(hexadecimal).
  • Y para palabras de dos bytes (16 bits), se usan sólo cuatro dígitos hexadecimales. (El número 16 aparece mucho cuando se habla de ordenadores.)
  • Para 32 bits: 8 dígitos hexadecimales, y sucesivamente.

Con la práctica podrás hacer conversiones de hexadecimal a binario de memoria:

3E equivale a 00111110

AA equivale a 10101010

Generalizando

Un número en base n sólo puede estar formado por dígitos entre 0 y n-1, por ejemplo, en base 2 sólo se admiten los dígitos 0 y 1; en base 8, los dígitos 0 a 7; en base 10, los dígitos 0 a 9.

Así, por ejemplo, en base 2 el número 2 se expresa como 10, en base 8 u octal, el número 8 se expresa como 10,en base 10 o decimal el número 10 se expresa como 10 y en base 16 o hexadecimal, el número 16 se expresa como 10..

Así que en general, el valor de un número expresado en base n será:

Número en base 'n': "abcde"

Valor: e*n0 + d*n1 + c*n2 + b * n3 + a*n4

Donde "nx" se lee como n elevado a la x potencia.

Algoritmo para conversión de bases

Ahora veamos el algoritmo para hacer un conversor universal.

Supongamos que el número está en un array que se llama "Numero":

char Numero[] = "56652";
  1. Lo primero, en un programa bien hecho, habría que comprobar que el número cumple las reglas, es decir, que no hay dígitos prohibidos en el sistema de numeración que usamos.
  2. Necesitamos el número de dígitos:
int NDigitos = strlen(Numero);
int Base = 8; /* Para base 8, será 16 para hexadecimal y 2 para binario */
  1. Empezaremos a recorrer el número desde el final, así que el primer exponente será 0, cualquier número elevado a 0 es 1. En lugar de calcular nDigitoNo, calcularemos el multiplicador, que se puede obtener multiplicando la base por el multiplicador anterior. Por ejemplo, para base 10 la secuencia de multiplicadores es 1, 10, 100, 1000, 10000, etc, para base 8 es 1, 8, 64, 512, etc
int Multiplicador=1;
int DigitoNo = NDigitos-1; /* Los arreglos tienen índices empezando por el 0 */
Valor = 0;
  1. Recorremos el número desde el final: Numero[DigitoNo]
while(DigitoNo >= 0)
{
   Valor += ValorDigito(Numero[DigitoNo])*Multiplicador;
   Multiplicador *= Base;
   DigitoNo--;
}
  1. El resultado será Valor.

Además, necesitamos una función que calcule el valor de un dígito en formato ASCII y lo convierta a int. Para que sirva para el sistema hexadecimal debe entender los caracteres '0' a '9', 'a' a 'f' y 'A' a 'F'.

int ValorDigito(char d)
{
   if(d >= '0' && d <= '9') return d-'0';
   if(d >= 'a' && d <= 'f') return 10+d-'a';
   if(d >= 'A' && d <= 'F') return 10+d-'A';
   return -1; /* Carácter prohibido */
}

Eso es todo.

Programa en C

Nombre Fichero Fecha Tamaño Contador Descarga
Conversor convert.zip 2000-12-01 1726 bytes 349