Hace tiempo tuve la necesidad de hacer una función de cambios de base, pero que no estuviera limitada, es decir, no tuviera definido qué base vamos a introducir y qué base debe devolver. Es decir, convertiremos un número en base b1 a base b2; la limitación, el número de caracteres con los que contemos, en el ejemplo hay hasta base 36, y es fácil extenderlo hasta base256… un número en hexadecimal no tiene desde el 0 al 9 y de la A a la F, pues un base36, del 0 al 9 y de la A a la Z. Con un poco de imaginación podremos sacar muchas ideas de este fragmento. Incluye programa de ejemplo:
Hace tiempo tuve la necesidad de hacer una función de cambios de base, pero que no estuviera limitada, es decir, no tuviera definido qué base vamos a introducir y qué base debe devolver. Es decir, convertiremos un número en base b1 a base b2; la limitación, el número de caracteres con los que contemos, en el ejemplo hay hasta base 36, y es fácil extenderlo hasta base64, base256, por ejemplo… con un poco de imaginación podremos sacar muchas ideas de este fragmento. Incluye programa de ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include <stdio.h> #include <string.h> #include "strutils.h" void cambiobase (char *n1, int b1, char *n2, int b2) { int lnum = strlen(n1); /* Longitud de nuestro número */ /* Caracteres que forman todos los posibles números hasta base 36 */ char numeros[37]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int divide; int i; int posn=0; int long2; do { divide = 0; long2 = 0; /* Será un puntero de n1, */ /* ya que iremos modificando su valor, long2 */ /* nos indicará por dónde vamos */ for (i=0; i<lnum; i++) { /* divide vale lo que valía antes multiplicado por la base + el número que acabamos de extraer */ /* que coincidirá con la posición del carácter dentro del array de numeros[] */ divide=divide*b1+strchr(numeros, n1[i])-(char*)&numeros; if (divide>=b2) { /* Si el número resultante es mayor o igual a la base */ n1[long2] = numeros [(int) divide / b2]; /* Modificaremos el dígito long2 de n1, */ /* y este será el número divide/b2 en base b1 */ divide = divide % b2; /* divide será el resto de la división */ long2++; } else if (long2>0) { n1[long2] = '0'; /* divide<b2, pero en iteraciones anteriores ha sido >= */ long2++; } } lnum=long2; /* hemos hallado un dígito de n2. Su valor será divide */ n2[posn] = numeros[divide]; posn++; /* posn es el puntero del nuevo número */ } while (long2!=0); n2[posn] = '\0'; n2=strrev(n2, posn); } int main() { char num1[20], num2[20]; int base1, base2; printf("Numero a convertir:"); scanf("%s", num1); printf("¿En qué base está ese número? "); scanf("%d", &base1); printf("¿A qué base quieres convertirlo? "); scanf("%d", &base2); cambiobase(num1, base1, num2, base2); printf("\n%s\n", num2); return 0; } |
La idea principal la saqué hace tiempo de un código escrito en otro lenguaje.
Tenemos que tener en cuenta que esta función utiliza a strutils.h (ver anterior post), aunque también podéis copiar directamente la función strrev y a compilar!!
Todo esto es debido a que el algoritmo para cambiar la base genera el número (como una cadena, pero al fin y al cabo un número) al revés, es decir el dígito de menor peso primero.
Leave a Reply