Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: DanielPy en 14 Febrero 2015, 18:05 pm



Título: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: DanielPy en 14 Febrero 2015, 18:05 pm
Hola a todos.
Nuevamente con alguna duda y solicitando ayuda.-
La duda es sobre cómo establecer  el valor correcto de la variable bits, si bien practicando un poco tal vez lograría que si por ej. El ingreso es:
2147483648 en binario  10000000000000000000000000000000
Obtendría el resultado esperado pero no me quedaría claro por qué establecí dicho valor.-   
Me podrían decir el criterio que debo utilizar para establecer el valor correcto en la variable bits.-

Código
  1. //Programa que convierte un número entero sin signo a binario.
  2. #include <stdio.h>
  3. #include <windows.h>
  4. #include <limits.h>
  5.  
  6. void ingreso();
  7. void decimalBinario(int numero);
  8.  
  9. int main(void){
  10. ingreso();
  11.  
  12. return 0;
  13. }
  14.  
  15. void ingreso(){
  16. int ingreso, ch=0, ok=0;
  17.  
  18. do{
  19. system("cls");
  20. printf("\n\n Ingrese un entero sin signo en el rango de 1 a %d...: ", INT_MAX);
  21. ok = scanf("%d", &ingreso) == 1 && ingreso > 0 && ingreso <= INT_MAX;
  22. while ((ch = getchar()) != EOF && ch != '\n');
  23. }while(!ok);
  24.  
  25. decimalBinario(ingreso);
  26. }
  27.  
  28. void decimalBinario(int numero){
  29. int bits=64, i, entero=0;
  30.  
  31. printf("\n\n binario ");
  32. for(i=0; bits > 0; i++){
  33. if(numero & bits){
  34. printf("1");
  35. entero += bits;
  36. }
  37. else{
  38. printf("0");
  39. }
  40. bits /=2;
  41. }
  42. printf(" ==> decimal %d\n\n", entero);
  43. }
  44.  
Saludos.
Daniel


Título: Re: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: ivancea96 en 14 Febrero 2015, 18:41 pm
Plantéate poner while(bits>0) en vez del for.

bits = 2^(sizeof(int)*8-1)
(?)


Título: Re: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: engel lex en 14 Febrero 2015, 18:51 pm
en tu caso hiciste una comparación binaria, sin embargo hay cosas en tu codigo que deberían ser corregidas

esto está mal
Código:
bits = 64

ya que el numero más grande que puede calcular en binario es 64

Código
  1. for(i=0; bits > 0; i++){
  2. if(numero & bits){
  3. printf("1");
  4. entero += bits;
  5. }
  6. else{
  7. printf("0");
  8. }
  9. bits /=2;
  10. }
  11. printf(" ==> decimal %d\n\n", entero);

cada ciclo ve si bits > 0, luego hace un and entre bits y el numero... (de estar bien) es algo así

Código:
numero = 1000
ciclo 1:
1111101000 AND
1000000000
compara a 0 e imprime, luego divide bit/2
ciclo 2:
1111101000 AND
0100000000
compara a 0 e imprime, luego divide bit/2
ciclo 3:
1111101000 AND
0010000000
compara a 0 e imprime, luego divide bit/2
.... etc hasta que bit == 0


agrego:-----

Citar
Plantéate poner while(bits>0) en vez del for.

bits = 2^(sizeof(int)*8-1)
(?)

ivancea96 recuerda que "^" es XOR, es mejor plantearlo como
Código
  1. 1<<(sizeof(int)*8-1)


Título: Re: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: BlackZeroX en 14 Febrero 2015, 20:09 pm
yo lo llegue a hacer con esto en alguna ocasión en la cual estaba de por medio el tiempo un examen profesional por tiempo :)

http://www.tutorialspoint.com/cprogramming/c_bit_fields.htm
http://en.cppreference.com/w/cpp/language/bit_field

Dulces Lunas!¡.l


Título: Re: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: Blaster en 14 Febrero 2015, 21:45 pm
Si la idea es convertir cualquier entero sin signo a su equivalente binario, lo mas conveniente seria trabajar con unsigned mas en tu caso ya que 2147483648 ya no es representable por un simple int ya estaría provocando un desbordamiento de enteros. Y ahora para establecer la mascara de bit necesaria lo mas correcto (teniendo en cuenta lo dicho) y portable seria:

Código
  1. unsigned bits = 1U << sizeof(unsigned) * CHAR_BIT - 1;

Un Saludo


Título: Re: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: rir3760 en 15 Febrero 2015, 02:30 am
La duda es sobre cómo establecer  el valor correcto de la variable bits, si bien practicando un poco tal vez lograría que si por ej. El ingreso es:
2147483648 en binario ? 10000000000000000000000000000000
Obtendría el resultado esperado pero no me quedaría claro por qué establecí dicho valor.-   
Me podrían decir el criterio que debo utilizar para establecer el valor correcto en la variable bits.
Algunos comentarios solo para redondear el tema:

* No es necesario comparar el valor leído contra INT_MAX ya que no hay forma de que sea mayor que este, esa comparación la debes eliminar.

* No es necesario calcular el valor ya que este ya lo tienes y lo pasas como argumento a la función "decimalBinario", otra cosa seria procesar una cadena con la representación del numero en base 2 y en base a esta obtener el numero.

* No es necesario un contador para controlar el bucle de la función, en su lugar terminas este cuando la mascara sea cero:
Código
  1. void decimalBinario(int numero)
  2. {
  3.   unsigned bit = 1U << sizeof(unsigned) * CHAR_BIT - 1;
  4.  
  5.   while (bit){
  6.      putchar(numero & bit ? '1' : '0');
  7.      bit >>= 1;
  8.   }
  9.  
  10.   putchar('\n');
  11. }

Un saludo


Título: Re: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: DanielPy en 15 Febrero 2015, 14:04 pm
Hola a todos.
Gracias a los cuatro por la ayuda que me brindan.-
Adopte el while como me sugirieron, luego coloque la línea de código de Blaster (que es similar a la de ivancea96) y todo funciona.-
BlackZeroX (Astaroth), no es mi fuerte el inglés.-

Citar
* No es necesario comparar el valor leído contra INT_MAX ya que no hay forma de que sea mayor que este, esa comparación la debes eliminar.
     
Esta línea no me cierra, si yo no efectuó esa comprobación el resultado es incorrecto.-
Por último y para que no piensen que estoy desaparecido escribí esto, pero lo que le sigue en importancia para mí no lo pongo todavía porque ni se me antoja como preguntarlo, ya me caerá la ficha y además quiero practicar un poco para ver si lo logro.-
 
Saludos.
Daniel


Título: Re: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: rir3760 en 15 Febrero 2015, 16:58 pm
Citar
No es necesario comparar el valor leído contra INT_MAX ya que no hay forma de que sea mayor que este, esa comparación la debes eliminar.

Esta línea no me cierra, si yo no efectuó esa comprobación el resultado es incorrecto.
Si te da un resultado incorrecto sera por alguna otra razón.

Cuando llamas a scanf esta consume los caracteres de la entrada estándar y en base a ellos almacena un valor de tipo signed int en la variable en cuestion, ese valor siempre estará en el rango [INT_MIN, INT_MAX].

En todo caso si actualizaste el programa publica su código fuente de nuevo.

Un saludo


Título: Re: De decimal a binario sumando sólo los bits encendidos [C].
Publicado por: DanielPy en 15 Febrero 2015, 18:24 pm
Tenías toda la razón, como esto te lo copié de un post (mío) que si mal no recuerdo se llamaba validar ingreso de datos en c no le di más vueltas al asunto y creí que debía emplearlo siempre.-
De cualquier manera dejo la foto del código que estoy finalizando con los apuntes complementarios para luego repasarlos.-

(http://i58.tinypic.com/5l70cy.jpg)

Saludos.
Daniel