Programa para convertir Decimal - Binario - Hexadecimal - Octal

Iniciado por chinoman1993, 27 Agosto 2013, 16:50 PM

0 Miembros y 1 Visitante están viendo este tema.

chinoman1993

Hola ,como estan el otro día no tenia nada que hacer y aprovechando las vacaciones de la uni me puse a hacer un programa sencillo pero bastante util para resolver otro tipo de problemas, el programa realiza conversiones de decimal a binario,hexadecimal y octal y viceversa con los 4 sistemas.
Sientanse libres de dejar sus sugerencias para mejorar el codigo


#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
char* Decimal_a_Binario (int *decimal)
{
int i=0 ,*paso,*dec_aux;
char *bin,*aux;
paso = (int *) malloc (sizeof(int));
dec_aux = (int *) malloc (sizeof(int));
bin = (char *) malloc (sizeof(char)*32);
aux = (char *) malloc (sizeof(char)*3);
*paso = 0;
*dec_aux = *decimal;
strcpy (aux,"\0");
strcpy (bin,"\0");
while (true)
{
*paso=*decimal/2;
itoa (*decimal%2,aux,10);
*(aux+1) = '\0';
*decimal=*paso;
*(bin+i) = *(aux+0);
      *(aux+0) = '\0';
i++;
if (*paso == 0)
break;
}
*decimal = *dec_aux;
*(bin+i)='\0';
strrev (bin);
return bin;
free (paso);
free (dec_aux);
free (bin);
free (aux);
}
char* Decimal_a_Octal (int *decimal)
{
int i=0 ,*paso,*dec_aux;
char *oct,*aux;
paso = (int *) malloc (sizeof(int));
dec_aux = (int *) malloc (sizeof(int));
oct = (char *) malloc (sizeof(char)*12);
aux = (char *) malloc (sizeof(char)*3);
*paso = 0;
*dec_aux = *decimal;
strcpy (aux,"\0");
strcpy (oct,"\0");
while (true)
{
*paso=*decimal/8;
itoa (*decimal%8,aux,10);
*(aux+1) = '\0';
*decimal=*paso;
*(oct+i) = *(aux+0);
      *(aux+0) = '\0';
i++;
if (*paso == 0)
break;
}
*decimal = *dec_aux;
*(oct+i)='\0';
strrev (oct);
return oct;
free (paso);
free (dec_aux);
free (oct);
free (aux);
}
char* Decimal_a_Hexadecimal (int *decimal)
{
int i=0 ,*paso,*dec_aux;
char *hex,*aux;
paso = (int *) malloc (sizeof(int));
dec_aux = (int *) malloc (sizeof(int));
hex = (char *) malloc (sizeof(char)*12);
aux = (char *) malloc (sizeof(char)*3);
*paso = 0;
*dec_aux = *decimal;
strcpy (aux,"\0");
strcpy (hex,"\0");
while (true)
{
*paso=*decimal/16;
if (*decimal%16 < 10)
itoa (*decimal%16,aux,10);
else
{
switch (*decimal%16)
{
case 10:
*(aux+0) = 'A';
break;
case 11:
*(aux+0) = 'B';
break;
case 12:
*(aux+0) = 'C';
break;
case 13:
*(aux+0) = 'D';
break;
case 14:
*(aux+0) = 'E';
break;
case 15:
*(aux+0) = 'F';
break;
}
}
*(aux+1) = '\0';
*decimal=*paso;
*(hex+i) = *(aux+0);
*(aux+0) = '\0';
i++;
if (*paso == 0)
break;
}
*decimal = *dec_aux;
*(hex+i)='\0';
strrev (hex);
return hex;
free (paso);
free (dec_aux);
free (hex);
free (aux);
}
char* Binario_a_Hexadecimal (char *bin)
{
int i=0;
char *hex,*aux;
hex = (char *) malloc (sizeof(char)*12);
aux = (char *) malloc (sizeof(char)*5);
strcpy (hex, "\0");
strcpy (aux, "\0");
i = strlen (bin) - 1;
while (i >= 0)
{
*(aux+0) = *(bin+(i-3));
*(aux+1) = *(bin+(i-2));
*(aux+2) = *(bin+(i-1));
*(aux+3) = *(bin+i);
*(aux+4) = '\0';
for (int j = 0 ; j < 4 ; j++)
if (*(aux+j) != '0' && *(aux+j) != '1')
*(aux+j) = '0';
if (strcmp (aux,"0000") == 0)
strcat (hex ,"0");
else if (strcmp (aux,"0001") == 0)
strcat (hex ,"1");
else if (strcmp (aux,"0010") == 0)
strcat (hex ,"2");
else if (strcmp (aux,"0011") == 0)
strcat (hex ,"3");
else if (strcmp (aux,"0100") == 0)
strcat (hex ,"4");
else if (strcmp (aux,"0101") == 0)
strcat (hex ,"5");
else if (strcmp (aux,"0110") == 0)
strcat (hex ,"6");
else if (strcmp (aux,"0111") == 0)
strcat (hex ,"7");
else if (strcmp (aux,"1000") == 0)
strcat (hex ,"8");
else if (strcmp (aux,"1001") == 0)
strcat (hex ,"9");
else if (strcmp (aux,"1010") == 0)
strcat (hex ,"A");
else if (strcmp (aux,"1011") == 0)
strcat (hex ,"B");
else if (strcmp (aux,"1100") == 0)
strcat (hex ,"C");
else if (strcmp (aux,"1101") == 0)
strcat (hex ,"D");
else if (strcmp (aux,"1110") == 0)
strcat (hex ,"E");
else if (strcmp (aux,"1111") == 0)
strcat (hex ,"F");
i -= 4;
*(aux+0) = '\0';
}
strrev (hex);
return hex;
free (hex);
free (aux);
}
char* Binario_a_Octal (char *bin)
{
int i=0;
char *oct,*aux;
oct = (char *) malloc (sizeof(char)*12);
aux = (char *) malloc (sizeof(char)*4);
strcpy (oct, "\0");
strcpy (aux, "\0");
i = strlen (bin) - 1;
while (i >= 0)
{
*(aux+0) = *(bin+(i-2));
*(aux+1) = *(bin+(i-1));
*(aux+2) = *(bin+i);
*(aux+3) = '\0';
for (int j = 0 ; j < 3 ; j++)
if (*(aux+j) != '0' && *(aux+j) != '1')
*(aux+j) = '0';
if (strcmp (aux,"000") == 0)
strcat (oct ,"0");
else if (strcmp (aux,"001") == 0)
strcat (oct ,"1");
else if (strcmp (aux,"010") == 0)
strcat (oct ,"2");
else if (strcmp (aux,"011") == 0)
strcat (oct ,"3");
else if (strcmp (aux,"100") == 0)
strcat (oct ,"4");
else if (strcmp (aux,"101") == 0)
strcat (oct ,"5");
else if (strcmp (aux,"110") == 0)
strcat (oct ,"6");
else if (strcmp (aux,"111") == 0)
strcat (oct ,"7");
i -= 3;
*(aux+0) = '\0';
}
strrev (oct);
return oct;
free (oct);
free (aux);
}
int Binario_a_Decimal (char *bin)
{
int *decimal;
char *bin_aux,*aux;
decimal = (int *) malloc (sizeof(int));
bin_aux = (char *) malloc (sizeof(char)*32);
aux = (char *) malloc (sizeof(char)*2);
*decimal = 0;
strcpy (bin_aux,"\0");
strcpy (aux,"\0");
strcpy (bin_aux,bin);
strrev (bin_aux);
for (int i = 0 ; i < strlen (bin_aux) ; i++)
{
*(aux+0) = *(bin_aux+i);
*(aux+1) = '\0';
*decimal += (pow (2.0,i) * atoi(aux));
}
return *decimal;
free (decimal);
free (bin_aux);
free (aux);
}
int Hexadecimal_a_Decimal (char *hex)
{
int *decimal;
char *hex_aux,*aux;
decimal = (int *) malloc (sizeof(int));
hex_aux = (char *) malloc (sizeof(char)*12);
aux = (char *) malloc (sizeof(char)*2);
*decimal = 0;
strcpy (hex_aux,"\0");
strcpy (aux,"\0");
strupr (hex);
strcpy (hex_aux,hex);
strrev (hex_aux);
for (int i = 0 ; i < strlen (hex_aux) ; i++)
{
if (*(hex_aux+i) >= '0' && *(hex_aux+i) <= '9')
{
*(aux+0) = *(hex_aux+i);
*(aux+1) = '\0';
*decimal += (pow (16.0,i) * atoi(aux));
}
else
{
switch (*(hex_aux+i))
{
case 'A':
*decimal += (pow (16.0,i) * 10);
break;
case 'B':
*decimal += (pow (16.0,i) * 11);
break;
case 'C':
*decimal += (pow (16.0,i) * 12);
break;
case 'D':
*decimal += (pow (16.0,i) * 13);
break;
case 'E':
*decimal += (pow (16.0,i) * 14);
break;
case 'F':
*decimal += (pow (16.0,i) * 15);
break;
}
}
}
return *decimal;
free (decimal);
free (hex_aux);
free (aux);
}
char* Hexadecimal_a_Binario (char *hex)
{
char *bin;
bin = (char *) malloc (sizeof(char)*32);
strcpy (bin, "\0");
strupr (hex);
for (int i = 0 ; i < strlen (hex) ; i++)
{
switch (*(hex+i))
{
case '0':
strcat (bin ,"0000");
break;
case '1':
strcat (bin ,"0001");
break;
case '2':
strcat (bin ,"0010");
break;
case '3':
strcat (bin ,"0011");
break;
case '4':
strcat (bin ,"0100");
break;
case '5':
strcat (bin ,"0101");
break;
case '6':
strcat (bin ,"0110");
break;
case '7':
strcat (bin ,"0111");
break;
case '8':
strcat (bin ,"1000");
break;
case '9':
strcat (bin ,"1001");
break;
case 'A':
strcat (bin ,"1010");
break;
case 'B':
strcat (bin ,"1011");
break;
case 'C':
strcat (bin ,"1100");
break;
case 'D':
strcat (bin ,"1101");
break;
case 'E':
strcat (bin ,"1110");
break;
case 'F':
strcat (bin ,"1111");
break;
}
}
return bin;
free (bin);
}
char* Hexadecimal_a_Octal (char *hex)
{
char *oct ,*bin;
oct = (char *) malloc (sizeof(char)*12);
bin = (char *) malloc (sizeof(char)*32);
strcpy (oct, "\0");
strcpy (bin, "\0");
strupr (hex);
bin = Hexadecimal_a_Binario (hex);
oct = Binario_a_Octal (bin);
return oct;
free (oct);
free (bin);
}
int Octal_a_Decimal (char *oct)
{
int *decimal;
char *oct_aux,*aux;
decimal = (int *) malloc (sizeof(int));
oct_aux = (char *) malloc (sizeof(char)*12);
aux = (char *) malloc (sizeof(char)*2);
*decimal = 0;
strcpy (oct_aux,"\0");
strcpy (aux,"\0");
strcpy (oct_aux,oct);
strrev (oct_aux);
for (int i = 0 ; i < strlen (oct_aux) ; i++)
{
*(aux+0) = *(oct_aux+i);
*(aux+1) = '\0';
*decimal += (pow (8.0,i) * atoi(aux));
}
return *decimal;
free (decimal);
free (oct_aux);
free (aux);
}
char* Octal_a_Binario (char *oct)
{
char *bin;
bin = (char *) malloc (sizeof(char)*32);
strcpy (bin, "\0");
for (int i = 0 ; i < strlen (oct) ; i++)
{
switch (*(oct+i))
{
case '0':
strcat (bin ,"000");
break;
case '1':
strcat (bin ,"001");
break;
case '2':
strcat (bin ,"010");
break;
case '3':
strcat (bin ,"011");
break;
case '4':
strcat (bin ,"100");
break;
case '5':
strcat (bin ,"101");
break;
case '6':
strcat (bin ,"110");
break;
case '7':
strcat (bin ,"111");
break;
}
}
return bin;
free (bin);
}
char* Octal_a_Hexadecimal (char *oct)
{
char *hex ,*bin;
hex = (char *) malloc (sizeof(char)*12);
bin = (char *) malloc (sizeof(char)*32);
strcpy (hex, "\0");
strcpy (bin, "\0");
strupr (hex);
bin = Octal_a_Binario (oct);
hex = Binario_a_Hexadecimal (bin);
return hex;
free (hex);
free (bin);
}
int main ()
{
int *decimal,*opc;
char *bin,*oct,*hex;
decimal = (int *) malloc (sizeof(int));
opc = (int *) malloc (sizeof(int));
bin = (char *) malloc (sizeof(char)*32);
oct = (char *) malloc (sizeof(char)*12);
hex = (char *) malloc (sizeof(char)*12);
*decimal = 0;
*opc = 0;
strcpy (bin, "\0");
strcpy (oct,"\0");
strcpy (hex,"\0");
printf("Convertir de decimal a otros sistemas press 1\n");
printf("Convertir de hexadecimal a otros sistemas press 2\n");
printf("Convertir de binario a otros sistemas press 3\n");
printf("Convertir de octal a otros sistemas press 4\n");
printf("opcion: ");
scanf ("%d", &*opc);
system("cls");
switch (*opc)
{
case 1:
printf ("Ingresa un numero decimal: ");
scanf ("%d" ,&*decimal);
printf ("Decimal: %d \nBinario: %s \nOctal: %s \nHexadecimal: %s\n",*decimal,Decimal_a_Binario(decimal),Decimal_a_Octal(decimal),Decimal_a_Hexadecimal(decimal));
break;
case 2:
printf ("Ingresa un numero hexadecimal: ");
fflush (stdin);
gets (hex);
printf ("Hexadecimal: %s \nDecimal: %d \nBinario: %s \nOctal: %s\n",hex,Hexadecimal_a_Decimal(hex),Hexadecimal_a_Binario(hex),Hexadecimal_a_Octal(hex));
break;
case 3:
printf ("Ingresa un numero binario: ");
fflush (stdin);
gets (bin);
printf ("Binario: %s \nDecimal: %d \nHexadecimal: %s \nOctal: %s\n",bin,Binario_a_Decimal(bin),Binario_a_Hexadecimal(bin),Binario_a_Octal(bin));
break;
case 4:
printf ("Ingresa un numero octal: ");
fflush (stdin);
gets (oct);
printf ("Octal: %s \nDecimal: %d \nHexadecimal: %s \nBinario: %s\n",oct,Octal_a_Decimal(oct),Octal_a_Hexadecimal(oct),Octal_a_Binario(oct));
break;
}
system("pause");
free (opc);
free (decimal);
free (hex);
free (oct);
free (bin);
return 0;
}

do-while

#1
¡Buenas!

Buf, que lío..., no porque el código esté mal (si te digo la verdad no lo he leído de forma detallada), sino porque utilizas muchas funciones para las conversiones. Si lo piensas detenidamente solo te hacen falta tres funciones para realizar cualquier conversión (realmente una sola función de conversión y dos funciones de apoyo).

Es largo para explicarlo paso por paso, así que te dejo un código para que veas la lógica:


#include <stdio.h>
#include <string.h>

//comprobamos que "representacion" sea un numero compuesto por cifras del primer parametro
int correcto(char *cifras, char *representacion, unsigned int base)
{
   char *posicion;
   int i;

   if(strlen(cifras) < 2 || base < 2 || base > strlen(cifras))
       return 0;

   for(i = 0 ; representacion[i] && (posicion = strchr(cifras , representacion[i])) && (posicion - cifras < base) ; i++);

   return !representacion[i];
}

//obtenemos el valor decimal de "representacion" que tendra que estar formado por cifras del primer parametro
unsigned long obtener_valor(char *cifras, char *representacion, unsigned int base)
{
   int i;
   unsigned long valor = 0;

   if(!correcto(cifras , representacion , base))
       return 0;

   for(i = 0 ; representacion[i] ; i++)
   {
       valor *= base;
       valor += strchr(cifras , representacion[i]) - cifras;
   }

   return valor;
}

//pasamos el numero "valor" a una representacion en la base "base"
char* obtener_representacion(char *cifras, unsigned long valor, unsigned int base)
{
   int i,j;
   static char representacion[33]; //hasta 32 bits
   char aux;

   for(i = 0 ; valor ; i++)
   {
       representacion[i] = cifras[valor % base];
       valor /= base;
   }

   representacion[i] = '\0';

   i--;

   for(j = 0 ; j < i ; j++,i--)
   {
       aux = representacion[i];
       representacion[i] = representacion[j];
       representacion[j] = aux;
   }

   return representacion;
}

//autoexplicativo...
char* cambiar_base(char *cifras, char *representacion, unsigned int base_inicial, unsigned long base_final)
{
   char aux;
   int i,j;
   unsigned long valor;

   if(!correcto(cifras,representacion,base_inicial))
       return NULL;

   if(base_final < 2 || base_final > strlen(cifras))
       return NULL;

   valor = obtener_valor(cifras,representacion, base_inicial);

   for(i = 0 ; valor ; i++)
   {
       representacion[i] = cifras[valor % base_final];
       valor /= base_final;
   }

   representacion[i] = '\0';

   i--;

   for(j = 0 ; j < i ; j++,i--)
   {
       aux = representacion[i];
       representacion[i] = representacion[j];
       representacion[j] = aux;
   }

   return representacion;
}

//cambiamos el conjunto de cifras del sistema numerico
char* intercambiar_cifras(char *cifras_antiguas, char *cifras_nuevas, char *representacion, unsigned int base)
{
   int i;

   if(!correcto(cifras_antiguas,representacion,base))
       return NULL;

   if(strlen(cifras_nuevas) < 2 || base < 2 || base > strlen(cifras_nuevas))
       return NULL;

   for(i = 0 ; representacion[i] ; i++)
       representacion[i] = cifras_nuevas[strchr(cifras_antiguas,representacion[i]) - cifras_antiguas];

   return representacion;
}

int main(int argc, char *argv[])
{
   unsigned long valor = 10023629;
   char cadena[50];// = "10023629";
   char cifras1[] = "0123456789ABCDEFGHIJKLMONPQRSTUVWXYZ";
   char cifras2[] = "1aH0KLy26Au3Uwq!·$%&/()=?¿[]{}-_.:,;";

   //convertimos el valor inicial en una representacion en base 6
   strcpy(cadena,obtener_representacion(CIFRAS,valor,6));

   printf("%s:6\n",cadena);

   //obtenemos el valor en decimal y lo mostramos
   printf("%lu:10\n",obtener_valor(cifras1,cadena,6));

   //realizamos distintas conversiones y vemos que todo va bien
   printf("%s:16\n",cambiar_base(cifras1,cadena,6,16));
   printf("%s:10\n",cambiar_base(cifras1,cadena,16,10));
   printf("%s:7\n",cambiar_base(cifras1,cadena,10,7));
   printf("%s:6\n",cambiar_base(cifras1,cadena,7,6));
   printf("%s:2\n",cambiar_base(cifras1,cadena,6,2));
   printf("%s:8\n",cambiar_base(cifras1,cadena,2,8));
   printf("%s:10\n",cambiar_base(cifras1,cadena,8,10));
   printf("%s:25\n",cambiar_base(cifras1,cadena,10,25));

   //y para terminar cambiamos las cifras del sistema numerico
   printf("%s\n",intercambiar_cifras(cifras1,cifras2,cadena,25));

   //y comprobamos que el numero sigue siendo el mismo:
   printf("%lu\n",obtener_valor(cifras2,cadena,25));

   return 0;
}


A parte de las funciones de comprobación, conversión y de cambio de base, he añadido una función que te convierte un unsigned long en una cadena que representa el número en la base que le indiques, y una segunda función que cambia la representación de las cifras de una base (esta última puede ser divertida...)

¡Saludos!

PD: Este código de aqui arriba tiene una pega muy grande. Tienes que estar acordandote en todo momento de cual ha sido la ultima base utilizada y del conjunto de cifras que has utilizado, por lo que te recomendaría utilizar un struct para guardar toda esa información. Por ejemplo:

struct BasesNumericas
{
   char *representacion;
   char *cifras;
   unsigned int base;
};


y podrías utilizarla como sigue:



int main(int argc, char *argv[])
{
   struct BasesNumericas datos;
   unsigned long valor = 10023629;
   char cadena[50];// = "10023629";
   char cifras1[] = "0123456789ABCDEFGHIJKLMONPQRSTUVWXYZ";
   char cifras2[] = "1aH0KLy26Au3Uwq!·$%&/()=?¿[]{}-_.:,;";

   //guardamos los datos que vamos a utilizar
   datos.representacion = cadena;
   datos.cifras=cifras1;
   //...

   //convertimos el valor inicial en una representacion en base 6
   strcpy(cadena,obtener_representacion(CIFRAS,valor,6));

   printf("%s:6\n",cadena);

   //obtenemos el valor en decimal y lo mostramos
   printf("%lu:10\n",obtener_valor(cifras1,cadena,6));

   //realizamos distintas conversiones y vemos que todo va bien
   //despues de cada una de las operaciones, o mejor despues de la ultima
   //guardamos en datos.base la ultima base utilizada.

   printf("%s:16\n",cambiar_base(cifras1,cadena,6,16));
   printf("%s:10\n",cambiar_base(cifras1,cadena,16,10));
   printf("%s:7\n",cambiar_base(cifras1,cadena,10,7));
   printf("%s:6\n",cambiar_base(cifras1,cadena,7,6));
   printf("%s:2\n",cambiar_base(cifras1,cadena,6,2));
   printf("%s:8\n",cambiar_base(cifras1,cadena,2,8));
   printf("%s:10\n",cambiar_base(cifras1,cadena,8,10));
   printf("%s:25\n",cambiar_base(cifras1,cadena,10,25));

   //y para terminar cambiamos las cifras del sistema numerico
   printf("%s\n",intercambiar_cifras(cifras1,cifras2,cadena,25));

   //nos apuntamos cual ha sido el ultimo conjunto de cifras usado
   datos.cifras=cifras2;

   //y comprobamos que el numero sigue siendo el mismo:
   printf("%lu\n",obtener_valor(cifras2,cadena,25));

   return 0;
}


¡Saludos!

Y ahora incluso podrías modificar las funciones para que reciban como parámetro un struct de estos, y ajustar los campos del struct dentro de las funciones de forma automática...

PD2: El código se puede hacer mas general todavía, si observamos que para construir el número no es necesario saber cual es la cifra que hay en una determinada posición, sino que lo que realmente importa es la posición que ocupa la cifra dentro del conjunto de cifras que estamos manejando.

Por lo tanto nos bastaría con tener una representación del numero en la que cada posición indique el indice de la cifra dentro de un conjunto de cifras, así se consigue hacer independiente la representación del número del conjunto de cifras que se utilizan.

Por ejemplo la cantidad 10 en base 3 con cifras decimales será 101, pero si en lugar de las cifras decimales utilizamos el conjunto de cifras {a,b,c} dicha representación será bab, por lo que internamente solo importa la posición de las cifras y el número se puede representar como una lista de indices enteros int indices[] = {1,0,1};. Así si tenemos un conjunto de cifras char cifras[] = {primera_cifra, segunda_cifra, tercera_cifra,...,'\0'};, para obtener la representación del número con este conjunto de cifras solo tendremos que hacer char representacion[] = {cifras[indice[0]],cifras[indice[1]],cifras[indice[2]],'\0'};, y nos podemos olvidar de pasar a las funciones los conjuntos de cifras que queremos utilizar.

Esta forma de hacer las cosas es mas general y mas abstracta, pero evita las limitaciones de trabajar con un conjunto determinado de cifras y te permite poder crear funciones "sencillas" para realizar las operaciones aritméticas básicas, ya que solo te hará falta controlar el indice de cada cifra, por lo que con operaciones de modulo y con una variable acumulador podrás realizarlas.

Ejemplo de suma en base 3:
[1][0][2] + [2][1][2]

2 + 2 = 4 --> 4/3 = 1 --> acumulador = 1, 4%3 = 1 ---> Acumulador = 1, ultimo índice = 1

0 + 1 + acumulador = 1 --> acumulador = 1/3 = 0, penúltimo índice = 1%3 = 1

1 + 2 + acumulador = 3 --> acumulador = 3/3 = 1, segundo índice = 3%3 = 0

0 + 0 + acumulador = 1 --> acumulador = 1 / 3 = 0, primero índice = 1%3 = 1

acumulador = 0. Hemos terminado. El conjunto de índice que representa la suma es {1,0,1,1}

Luego con las cifras {abc} la representación será babb, y con cifras decimales 1011

¡Saludos!
- Doctor, confundo los números y los colores.
- Vaya marrón.
- ¿Marrón? ¡Por el culo te la hinco!