Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Función decimal -> binario

Estas en el tema de Función decimal -> binario en el foro de C/C++ en Foros del Web. Hola buenas, estoy dando mis primeros pinitos en el mundo de la programación y me he encontrado con un problema que no sé resolver. Intento ...
  #1 (permalink)  
Antiguo 05/04/2015, 08:47
Avatar de tur2ra  
Fecha de Ingreso: abril-2015
Ubicación: Delante de la pantalla
Mensajes: 6
Antigüedad: 9 años
Puntos: 0
Función decimal -> binario

Hola buenas,

estoy dando mis primeros pinitos en el mundo de la programación y me he encontrado con un problema que no sé resolver. Intento hacer una acción que muestre un número entrado en forma decimal en forma binaria. Sé que hay métodos recursivos que llaman a la misma función pero no es lo que busco. Quisiera poder tener ese número binario con las propiedades de un int.

Lo curioso de esto es que según con que números muestra el resultado correcto pero según con que otros no.

Les dejo lo que ahora estoy mantelando ya que por más que lo retoque siempre hay algun número que se me escapa.

void decimalAbinari(int x){
//Declarem variables
int binari=0, diferencia=x, comprovador=0, iteracio=1;
//ALGORITME
int b1=binari;
while (diferencia!=0){

int potencia=0;

if (diferencia==1){
b1=b1+1;
diferencia=diferencia-1;
cout << "entra a dif==1"<<endl;
}

else if (diferencia==2){
b1=b1+10;
diferencia=diferencia-2;
cout << "entra a dif==2" << endl;
}

else if (diferencia>2){
while(diferencia>=(pow(2, potencia+1)))potencia++;
b1=b1+pow(10, potencia);
diferencia=diferencia-pow(2, potencia);
cout << "entra a dif>2"<< endl;
}

else break;
}

Gracias por intentar ayudarme.
  #2 (permalink)  
Antiguo 05/04/2015, 09:28
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Función decimal -> binario

se me ocurre que puedes hacerlo usando el operador binario & para saber el estado de cada uno de sus bits y asi saber si es 1 o 0 y los vas concatenando.
  #3 (permalink)  
Antiguo 05/04/2015, 10:50
Avatar de tur2ra  
Fecha de Ingreso: abril-2015
Ubicación: Delante de la pantalla
Mensajes: 6
Antigüedad: 9 años
Puntos: 0
Respuesta: Función decimal -> binario

Lo siento, creo que no entiendo muy bien lo que quieres decir... Lo que me interesa es que este todo el resultado en forma decimal, por eso el binario le voy sumando 10^potencia, siendo esa potencia el mayor numero al que se puede elevar a 2 la diferencia (la cual se va restando dependiendo de la potencia que encuentre). Según lo veo pueden pasar dos cosas, depeniendo si es par o impar. Por eso lo de si diferencia==1 y diferencia==2. Siento si no queda lo bastante claro, puedo volver a subirlo con comentarios.

Gracias por contestar!
  #4 (permalink)  
Antiguo 05/04/2015, 11:27
Avatar de tur2ra  
Fecha de Ingreso: abril-2015
Ubicación: Delante de la pantalla
Mensajes: 6
Antigüedad: 9 años
Puntos: 0
Respuesta: Función decimal -> binario

Es que lo curioso es que en algunos valores me resta 1 usando exactamente el mismo algoritmo y en otras no. Por ejemplo:

Entro el 4 en decimal y me retorna 99 ( en lugar de 100)

entro el 32 y me retorna 100000 (correcto)

entro el 8 -> 1000 (correcto)

entro el 16 -> 9999 (fail)


No tengo ni idea de que probar ya
------------------------------------------------CÓDIGO----------------------------------------------

void decimalAbinari(int x){
//Declarem variables
int binari=0, diferencia=x;
//ALGORITME
while (diferencia!=0){
int potencia=0;

if (diferencia==1){
binari=binari+1;
diferencia=diferencia-1;
}

else if (diferencia==2){
binari=binari+10;
diferencia=diferencia-2;
}

else if (diferencia>2){
int potencia=0;
while(diferencia>(pow(2, potencia+1)))potencia++;
if(diferencia==(pow(2, potencia+1))){
potencia++;
binari=pow(10, potencia);
diferencia=0;
}
else{
binari=binari+pow(10, potencia);
diferencia=diferencia-pow(2, potencia);
}
}

else break;
}

Última edición por tur2ra; 05/04/2015 a las 11:31 Razón: adjunto código actualizado, con el que me pasa esto
  #5 (permalink)  
Antiguo 05/04/2015, 15:21
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Función decimal -> binario

sinceramente pienso que no deberias hacerlo asi. ¿Que pasa si por ejemplo metes 50000? Pues que al pasar a binario desborde el valor de un entero. Deberias pasarlo a char* y luego usas atoi o sprintf para pasarlo a entero. De todos modos mañana echare un vistazo a ver que haces mal.
  #6 (permalink)  
Antiguo 06/04/2015, 04:39
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Función decimal -> binario

Aquí lo tienes corregido:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. //Prototipo de funcion
  5. int DecimalToBinary(int x, int *overflow);
  6.  
  7. int main()
  8. {
  9.    int i, binario, error;
  10.  
  11.    // Como un entero tiene 4 bytes en mi maquina, si hago:
  12.    // (2^8)*4=1024 y como el 0 tambien cuenta, quiere decir que el rango valido
  13.    // es de 0 a 1023. Si intentaras imprimir un valor superior desbordarias el entero
  14.    for(i=0; i <= 1023; i++){
  15.       binario = DecimalToBinary(i, &error);
  16.       if(error == 1)
  17.          printf("Se desbordo el valor maximo posible para un entero binario.\n");
  18.       else
  19.          printf("%4d = %.10d\n", i, binario);
  20.    }
  21.    getchar();
  22.    return 0;
  23. }
  24. //---------------------------------------------------------------------------
  25.  
  26. int DecimalToBinary(int x, int *overflow){
  27.    //Declarem variables
  28.    int binary=0, potencia;
  29.  
  30.    //El valor maximo se saca elevando 2 al numero de bits de un byte que son 8
  31.    //y luego lo multiplicas por el numero de bytes del tipo
  32.    //Esto es util si se usa en una máquina en la que un entero tiene un tamaño diferente
  33.    int sizeMax = pow(2,8) * sizeof(int);
  34.  
  35.    if(x >= sizeMax){
  36.       *overflow=1;
  37.    }else{
  38.       *overflow = 0;
  39.       //ALGORITME
  40.       while (x != 0){
  41.          potencia=1; //¿para que empezar por 0?
  42.          if (x ==1 ){
  43.             binary++;
  44.             x--;
  45.          }else{ //Esta parte la he simplificado bastante
  46.             while(x > (pow(2, potencia)))
  47.                potencia++;
  48.             if(x < (pow(2, potencia)))
  49.                potencia--;
  50.             x -= pow(2, potencia);
  51.             binary += pow(10, potencia); //Aqui necesitabas sumar y tu asignabas
  52.          }
  53.       }
  54.    }
  55.    return binary;
  56. }
  57. //---------------------------------------------------------------------------

Si tienes alguna duda preguntala, la cuestion es que lo entiendas, no que lo copies sin mas.

Y aqui otro modo de hacerlo:
Código C:
Ver original
  1. int DecimalToBinary(int x, int *overflow)
  2. {
  3.    int binary=0;
  4.    int valueMax = 1024;
  5.    int digito;
  6.    int exponente = 1;
  7.  
  8.    if(x >= valueMax){
  9.       *overflow=1;
  10.    }else
  11.    {
  12.       *overflow = 0;
  13.       //ALGORITME
  14.       do{
  15.          //Obtenemos el valor del digito a escribir(0 ó 1)
  16.          digito = x % 2;
  17.          //Dividimos el numero por 2 para seguir
  18.          x /= 2;
  19.          //Añadimos el nuevo digito al numero binario
  20.          binary += digito * exponente;
  21.          //Aumentamos el exponente el exponente
  22.          exponente *= 10;
  23.       }while (x > 0);
  24.    }
  25.    return binary;
  26. }

Última edición por aguml; 06/04/2015 a las 07:20
  #7 (permalink)  
Antiguo 06/04/2015, 08:25
Avatar de tur2ra  
Fecha de Ingreso: abril-2015
Ubicación: Delante de la pantalla
Mensajes: 6
Antigüedad: 9 años
Puntos: 0
Respuesta: Función decimal -> binario

Buenos días aguml!

Para empezar tengo que darte las gracias. Me has ayudado lo que no está escrito...
Te digo que no tengo intención de copiar el código sin más, ni mucho menos, puesto que ahora mismo no estoy estudiando nada relacionado con este mundo, lo hago simplemente por aprender y ver si algún día puedo hacer algo útil en la sociedad. ;D


Bueno, te informo de los progresos:

1. Implementare una función en lugar de una acción, porque lo de pasar el parametro overflow lo veo cuánto menos necesario.

2. El primer algoritmo sigue sin dar los resultados esperados, algunos son correctos pero en otros tantos se cuelan 9, exactamente como sucedía con el que te pasé. Acabo de comprobarlo, y hasta el 127 funciona perfectamente. No alcanzo a ver el porque de eso.

3. El segundo algoritmo es una joya. Mucho más simple y eficaz, aunque no se me hubiese ocurrido lo del mod para saber si era par o impar. Intentaré recordarlo para los próximos programas que haga.
  #8 (permalink)  
Antiguo 06/04/2015, 10:14
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Función decimal -> binario

a mi el primer metodo me funciona y sobre el segundo, te aconsejo que busques info ya que realmente no es lo que piensas. Los pcs trabajan en binario y por eso todas sus medidas son multiplos de 2. El byte son 8 bits ¿Por que? Pues porque cuando se inicio todo esto pensaron que era lo que se necesitaba ya que con 8 bits se podia guardar cualquier valor de la tabla ASCII. Con 8 bits podemos almacenar 256 valores diferentes (de 0 a 255). Entonces lo que hago es dividir el valor entre 2 y el resto o residuo me da el estado del bit y asi hasta que de 0. Entonces por ejemplo para 10, 10/2=5 r=0; 5/2=2 r=1; 2/2=1 r=0; 1/2=0 r=1 y da 1010 ya que se van colocando de derecha a izquierda y por eso se usa una variable que se multiplica por diez en cada pasada.
  #9 (permalink)  
Antiguo 06/04/2015, 15:26
lareto
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: Función decimal -> binario

Cita:
Iniciado por tur2ra Ver Mensaje
El primer algoritmo sigue sin dar los resultados esperados...
Yo no pude reproducir el problema, pero de todos modos encuentro que hay un par de comparaciones que piden problemas:
Código:
while(x > (pow(2, potencia)))
Código:
if(x < (pow(2, potencia)))
x es un int, mientras que pow() devuelve un double (cuando los dos parámetros con los que se invoca son int); y no está bien comparar variables de tipo real con tipos enteros así como así.

Vale la pena imprimirse para leer en las próximas vacaciones:
https://www.topcoder.com/community/d...als-section-1/
(abajo en esa página hay un link a la section 2, no pasárselo)
  #10 (permalink)  
Antiguo 07/04/2015, 01:34
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Función decimal -> binario

Cita:
Iniciado por lareto Ver Mensaje
Yo no pude reproducir el problema, pero de todos modos encuentro que hay un par de comparaciones que piden problemas:
Código:
while(x > (pow(2, potencia)))
Código:
if(x < (pow(2, potencia)))
x es un int, mientras que pow() devuelve un double (cuando los dos parámetros con los que se invoca son int); y no está bien comparar variables de tipo real con tipos enteros así como así.

Vale la pena imprimirse para leer en las próximas vacaciones:
https://www.topcoder.com/community/d...als-section-1/
(abajo en esa página hay un link a la section 2, no pasárselo)
La verdad es que yo tampoco he sido capaz de que me salgan 9s. Uso C++Builder 6.
Si quieres algo mas potente puedes usar unsigned int64 que en mi caso me permite llegar hasta el 1048575U (0xFFFFF) que es 11111111111111111111 sin desbordarse.
La version que usa un unsigned int solo puede llegar hasta 1023U (0x3FF) que es 1111111111.
O sea que el int64 permite trabajar con binarios el doble de grandes.

Aqui el código:
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <math.h>
  4.  
  5. //Prototipo de funcion
  6. uint64_t DecimalToBinary64(int x, int *overflow);
  7. int DecimalToBinary32(int x, int *overflow);
  8. int ObtainLimitBinForInt32(void);
  9. int ObtainLimitBinForInt64(void);
  10. int ObtainMaxDigitsBinInt32(void);
  11. int ObtainMaxDigitsBinInt64(void);
  12.  
  13. int main()
  14. {
  15.    int i, error;
  16.    uint64_t binario;
  17.  
  18.    int numMax = ObtainLimitBinForInt64();
  19.    int maxLenBin = ObtainMaxDigitsBinInt64();
  20.  
  21.    for(i=0; i <= numMax; i++){
  22.       binario = DecimalToBinary64(i, &error);
  23.       if(error == 1)
  24.          printf("Se desbordo el valor maximo posible para un entero binario.\n");
  25.       else
  26.          printf("%6d = %.*I64u\n", i, maxLenBin, binario);
  27.    }
  28.    getchar();
  29.    return 0;
  30. }
  31. //---------------------------------------------------------------------------
  32.  
  33. //nos devuelve un entero binario de hasta 10 digitos
  34. int DecimalToBinary32(int x, int *overflow)
  35. {
  36.    int binary=0;
  37.    int digito;
  38.    int exponente = 1;
  39.    int binMax;
  40.    int producto;
  41.    int valueMax;
  42.  
  43.    valueMax = ObtainLimitBinForInt32();
  44.  
  45.    if(x > (int)valueMax){
  46.       *overflow=1;
  47.    }else
  48.    {
  49.       *overflow = 0;
  50.       //ALGORITME
  51.       exponente=1;
  52.  
  53.       do{
  54.          //Obtenemos el valor del digito a escribir(0 ó 1)
  55.          digito = x % 2;
  56.          //Dividimos el numero por 2 para seguir
  57.          x /= 2;
  58.          //Añadimos el nuevo digito al numero binario
  59.          binary += digito * exponente;
  60.          //Aumentamos el exponente el exponente
  61.          exponente *= 10;
  62.       }while (x > 0);
  63.    }
  64.    return binary;
  65. }
  66. //---------------------------------------------------------------------------
  67.  
  68. int ObtainLimitBinForInt32(void)
  69. {
  70.    int contador=0;
  71.    int binMax=1;
  72.    int producto;
  73.    int exponente=1;
  74.    int valueMax=0;
  75.  
  76.    //Obtengo el numero de digitos maximo para el tipo
  77.    contador = ObtainMaxDigitsBinInt32();
  78.  
  79.    //Obtengo el valor binario maximo para el tipo
  80.    contador--;
  81.    while(contador > 0){
  82.       binMax *= 10;
  83.       binMax += 1;
  84.       contador--;
  85.    }
  86.  
  87.    //Paso el valor binario maximo a decimal para obtener el decimal maximo permitido
  88.     while(binMax>0)
  89.     {
  90.         producto=0;
  91.         producto=exponente*(binMax%10);
  92.         valueMax+=producto;
  93.         exponente*=2;
  94.         binMax/=10;
  95.     }
  96.    return valueMax;
  97. }
  98. //---------------------------------------------------------------------------
  99.  
  100. int ObtainMaxDigitsBinInt32(void)
  101. {
  102.    //Obtengo el numero de digitos maximo para el tipo
  103.    int contador=0;
  104.    unsigned int valueMax=0;
  105.    valueMax--;
  106.  
  107.    //Cuento los digitos binarios
  108.    while(valueMax > 0){
  109.       valueMax /= 10;
  110.       contador++;
  111.    }
  112.    return contador;
  113. }
  114. //---------------------------------------------------------------------------
  115.  
  116. int ObtainMaxDigitsBinInt64(void)
  117. {
  118.    //Obtengo el numero de digitos maximo para el tipo
  119.    int contador=0;
  120.    uint64_t valueMax=0;
  121.    valueMax--;
  122.  
  123.    //Cuento los digitos binarios
  124.    while(valueMax > 0){
  125.       valueMax /= 10;
  126.       contador++;
  127.    }
  128.    return contador;
  129. }
  130. //---------------------------------------------------------------------------
  131.  
  132. int ObtainLimitBinForInt64(void)
  133. {
  134.    int contador=0;
  135.    uint64_t binMax=1;
  136.    int producto;
  137.    int exponente=1;
  138.    uint64_t valueMax=0;
  139.  
  140.    contador = ObtainMaxDigitsBinInt64();
  141.  
  142.    //Obtengo el valor binario maximo para el tipo
  143.    contador--;
  144.    while(contador > 0){
  145.       binMax *= 10;
  146.       binMax += 1;
  147.       contador--;
  148.    }
  149.  
  150.    //Paso el valor binario maximo a decimal para obtener el decimal maximo permitido
  151.     while(binMax>0)
  152.     {
  153.         producto=0;
  154.         producto=exponente*(binMax%10);
  155.         valueMax+=producto;
  156.         exponente*=2;
  157.         binMax/=10;
  158.     }
  159.    return valueMax;
  160. }
  161. //---------------------------------------------------------------------------
  162.  
  163. //nos devuelve un entero binario de hasta 19 digitos
  164. uint64_t DecimalToBinary64(int x, int *overflow)
  165. {
  166.    uint64_t binary=0;
  167.    int digito;
  168.    uint64_t exponente = 1;
  169.    uint64_t binMax;
  170.    int producto;
  171.    uint64_t valueMax;
  172.  
  173.    valueMax = ObtainLimitBinForInt64();
  174.  
  175.    if(x > valueMax){
  176.       *overflow=1;
  177.    }else
  178.    {
  179.       *overflow = 0;
  180.       //ALGORITME
  181.       exponente=1;
  182.  
  183.       do{
  184.          //Obtenemos el valor del digito a escribir(0 ó 1)
  185.          digito = x % 2;
  186.          //Dividimos el numero por 2 para seguir
  187.          x /= 2;
  188.          //Añadimos el nuevo digito al numero binario
  189.          binary += digito * exponente;
  190.          //Aumentamos el exponente el exponente
  191.          exponente *= 10;
  192.       }while (x > 0);
  193.    }
  194.    return binary;
  195. }
  196. //---------------------------------------------------------------------------
  #11 (permalink)  
Antiguo 07/04/2015, 02:27
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Función decimal -> binario

Lo siguiente ya seria usar un unsigned int64 como entrada y un array de caracteres como salida:
Código C:
Ver original
  1. void DecimalToBinaryString(uint64_t x, char* binary, int sizeMax, int *overflow)
  2. {
  3.    int digito;
  4.    int contador = sizeMax;
  5.    char *aux;
  6.  
  7.    if(sizeMax > 0){
  8.       aux=malloc(sizeMax);
  9.       if(aux != NULL){
  10.          memset(aux,0,sizeMax);
  11.          memset(binary,0,sizeMax);
  12.          *overflow=0;
  13.  
  14.          do{
  15.             contador--;
  16.             if(contador < 0){
  17.                *overflow=1;
  18.                memset(aux,0,sizeMax);
  19.             }else{
  20.                //Obtenemos el valor del digito a escribir(0 ó 1)
  21.                digito = x % 2;
  22.                //Dividimos el numero por 2 para seguir
  23.                x /= 2;
  24.                //Añadimos el nuevo digito al binario
  25.                aux[contador] = digito + 0x30;
  26.             }
  27.          }while (x > 0 && *overflow != 1);
  28.          strncpy(binary, &aux[contador], sizeMax-contador);
  29.          free(aux);
  30.       }
  31.    }
  32. }

y para probarla:
Código C:
Ver original
  1. char binari[100];
  2. uint64_t valor=11234567899999999901;
  3. DecimalToBinaryString(valor, binari, sizeof(binari), &error);
  4. if(error == 1)
  5.    printf("Se desbordo el valor maximo posible para un entero binario.\n");
  6. else
  7.    printf("%I64u = %s\n", valor, binari);

Esto nos permitiria obtener una cadena con el binario de un numero muy muy grande jejeje.

Última edición por aguml; 07/04/2015 a las 02:33
  #12 (permalink)  
Antiguo 07/04/2015, 13:16
Avatar de tur2ra  
Fecha de Ingreso: abril-2015
Ubicación: Delante de la pantalla
Mensajes: 6
Antigüedad: 9 años
Puntos: 0
Respuesta: Función decimal -> binario

buf... deu n'hi do! vaya telita con el problema... y yo que pensaba que era relativamente sencillo!!

Bueno os comento, probé la primera manera que dijiste aguml (los arrays mejor los dejo por otro momento xD)

He intentado entender el código y ciertamente gracias a los comentarios creo que me hago una idea. Hay una cosa pero que no logro dislumbrar, y es bastante importante además. En la muestra de el bit pones los siguientes carácteres:

else
printf("%6d = %.*I64u\n", i, maxLenBin, binario);

Me he imaginado que %6d es para mostrar un int, sin embargo el %.*I64u no logro ver como actúa. Si pudierais decirme de donde sacar información para hacer este tipo de muestra os lo agradecería eternamente, la verdad es que es mucho más práctico que tener que hacer las '<<' cada vez que quiero mostrar una variable.

Repito: Muchas gracias por todo, ojala algún día pueda ayudar a otros como ustedes me están ayudando a mí.

PD: ¿Cual es el método para embutir el código con tabuladores y color?
  #13 (permalink)  
Antiguo 07/04/2015, 14:01
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Función decimal -> binario

I64u es para mostrar un entero de 64 bits sin signo. Si quisieras con signo se pone I64d. El 6d muestra un entero con un minimo de 6 caracteres y si tiene menos se rellena con espacios a la izquierda. Para poner el codigo identado y con color usas Highlight y eliges el lenguaje deseado.
  #14 (permalink)  
Antiguo 07/04/2015, 14:05
Avatar de tur2ra  
Fecha de Ingreso: abril-2015
Ubicación: Delante de la pantalla
Mensajes: 6
Antigüedad: 9 años
Puntos: 0
Respuesta: Función decimal -> binario

Perfecto! Además acabo de probar el programa y muestra hasta 10^20 o sea que de lujo:D
  #15 (permalink)  
Antiguo 07/04/2015, 14:45
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Función decimal -> binario

pues si, la de 64 bits muestra valores binarios de hasta 10^20 y la que devuelve string 10^70 aproximadamente.

Etiquetas: binario, c++, conversion, decimal
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:13.