Imprima un int en representación binaria usando C

Estoy buscando una función que me permita imprimir la representación binaria de un int. Lo que tengo hasta ahora es;

char *int2bin(int a) { char *str,*tmp; int cnt = 31; str = (char *) malloc(33); /*32 + 1 , because its a 32 bit bin number*/ tmp = str; while ( cnt > -1 ){ str[cnt]= '0'; cnt --; } cnt = 31; while (a > 0){ if (a%2==1){ str[cnt] = '1'; } cnt--; a = a/2 ; } return tmp; } 

Pero cuando llamo

 printf("a %s",int2bin(aMask)) // aMask = 0xFF000000 

Obtengo resultados como;

0000000000000000000000000000000000xtpYy (Y un grupo de personajes desconocidos.

¿Es un defecto en la función o estoy imprimiendo la dirección de la matriz de caracteres o algo así? Lo siento, simplemente no puedo ver dónde me estoy equivocando.

NB El código es de aquí

EDITAR: No es tarea para su información, estoy tratando de depurar las rutinas de manipulación de imágenes de otra persona en un idioma desconocido. Sin embargo, si ha sido etiquetado como tarea porque es un concepto elemental, entonces juego limpio.

Aquí hay otra opción que está más optimizada donde pasa el búfer asignado. Asegúrate de que sea del tamaño correcto.

 // buffer must have length >= sizeof(int) + 1 // Write to the buffer backwards so that the binary representation // is in the correct order ie the LSB is on the far right // instead of the far left of the printed string char *int2bin(int a, char *buffer, int buf_size) { buffer += (buf_size - 1); for (int i = 31; i >= 0; i--) { *buffer-- = (a & 1) + '0'; a >>= 1; } return buffer; } #define BUF_SIZE 33 int main() { char buffer[BUF_SIZE]; buffer[BUF_SIZE - 1] = '\0'; int2bin(0xFF000000, buffer, BUF_SIZE - 1); printf("a = %s", buffer); } 

Algunas sugerencias:

  • null-termina su cadena
  • no uses números mágicos
  • compruebe el valor de retorno de malloc()
  • no eche el valor de retorno de malloc()
  • usa operaciones binarias en lugar de aritméticas ya que estás interesado en la representación binaria
  • no hay necesidad de repetir dos veces

Aquí está el código:

 #include  #include  char * int2bin(int i) { size_t bits = sizeof(int) * CHAR_BIT; char * str = malloc(bits + 1); if(!str) return NULL; str[bits] = 0; // type punning because signed shift is implementation-defined unsigned u = *(unsigned *)&i; for(; bits--; u >>= 1) str[bits] = u & 1 ? '1' : '0'; return str; } 

Su cadena no tiene terminación nula. Asegúrese de agregar un carácter '\0' al final de la cadena; o bien, puede asignarlo con calloc lugar de malloc , lo que pondrá a cero la memoria que le devuelve.

Por cierto, hay otros problemas con este código:

  • Tal como se utiliza, asigna memoria cuando la llama, lo que deja al llamante responsable de free() la cadena asignada. Perderá memoria si solo lo llama en una llamada de printf .
  • Hace dos pasadas sobre el número, lo cual es innecesario. Puedes hacer todo en un ciclo.

Aquí hay una implementación alternativa que podría usar.

 #include  #include  char *int2bin(unsigned n, char *buf) { #define BITS (sizeof(n) * CHAR_BIT) static char static_buf[BITS + 1]; int i; if (buf == NULL) buf = static_buf; for (i = BITS - 1; i >= 0; --i) { buf[i] = (n & 1) ? '1' : '0'; n >>= 1; } buf[BITS] = '\0'; return buf; #undef BITS } 

Uso:

 printf("%s\n", int2bin(0xFF00000000, NULL)); 

El segundo parámetro es un puntero a un búfer en el que desea almacenar la cadena de resultados. Si no tiene un búfer, puede pasar NULL e int2bin escribirá en un búfer static y se lo devolverá. La ventaja de esto sobre la implementación original es que la persona que llama no tiene que preocuparse de free() la cadena que se devuelve.

Un inconveniente es que solo hay un búfer estático, por lo que las llamadas subsiguientes sobrescribirán los resultados de llamadas anteriores. No se pudieron guardar los resultados de varias llamadas para su uso posterior. Además, no es seguro para el hilo, lo que significa que si llama a la función de diferentes hilos, podrían golpear las cuerdas del otro. Si esa es una posibilidad, necesitarás pasar tu propio búfer en lugar de pasar NULL , así:

 char str[33]; int2bin(0xDEADBEEF, str); puts(str); 

Aquí hay un algoritmo simple.

 void decimalToBinary (int num) { //Initialize mask unsigned int mask = 0x80000000; size_t bits = sizeof(num) * CHAR_BIT; for (int count = 0 ;count < bits; count++) { //print (mask & num ) ? cout <<"1" : cout <<"0"; //shift one to the right mask = mask >> 1; } } 

esto es lo que hice para mostrar un interger como un código binairy que está separado por 4 bits:

 int getal = 32; /** To determain the value of a bit 2^i , intergers are 32bits long**/ int binairy[getal]; /** A interger array to put the bits in **/ int i; /** Used in the for loop **/ for(i = 0; i < 32; i++) { binairy[i] = (integer >> (getal - i) - 1) & 1; } int a , counter = 0; for(a = 0;a<32;a++) { if (counter == 4) { counter = 0; printf(" "); } printf("%i", binairy[a]); teller++; } 

podría ser un poco grande, pero siempre lo escribo de una manera (espero) que todos puedan entender lo que está pasando. Espero que esto haya ayudado.

 #include //#include // use this if you are running your code in visual c++, linux don't // have this library. i have used it for getch() to hold the screen for input char. void showbits(int); int main() { int no; printf("\nEnter number to convert in binary\n"); scanf("%d",&no); showbits(no); // getch(); // used to hold screen... // keep code as it is if using gcc. if using windows uncomment #include & getch() return 0; } void showbits(int n) { int i,k,andmask; for(i=15;i>=0;i--) { andmask = 1 << i; k = n & andmask; k == 0 ? printf("0") : printf("1"); } } 

Dos cosas:

  1. ¿Dónde pones el personaje NUL? No puedo ver un lugar donde '\0' esté configurado.
  2. Int está firmado, y 0xFF000000 se interpretaría como un valor negativo. Entonces, while (a > 0) será falso inmediatamente.

Aparte: la función malloc en el interior es fea. ¿Qué hay de proporcionar un buffer para int2bin?

Un par de cosas:

 int f = 32; int i = 1; do{ str[--f] = i^a?'1':'0'; }while(i<<1); 
  • Es altamente dependiente de la plataforma, pero tal vez esta idea anterior te permita comenzar.
  • ¿Por qué no usar memset (str, 0, 33) para establecer toda la matriz de caracteres a 0?
  • No te olvides de gratis () !!! la matriz char * después de su llamada de función!

Dos versiones simples codificadas aquí (reproducidas con reformateo suave).

 #include  /* Print n as a binary number */ void printbitssimple(int n) { unsigned int i; i = 1<<(sizeof(n) * 8 - 1); while (i > 0) { if (n & i) printf("1"); else printf("0"); i >>= 1; } } /* Print n as a binary number */ void printbits(int n) { unsigned int i, step; if (0 == n) /* For simplicity's sake, I treat 0 as a special case*/ { printf("0000"); return; } i = 1<<(sizeof(n) * 8 - 1); step = -1; /* Only print the relevant digits */ step >>= 4; /* In groups of 4 */ while (step >= n) { i >>= 4; step >>= 4; } /* At this point, i is the smallest power of two larger or equal to n */ while (i > 0) { if (n & i) printf("1"); else printf("0"); i >>= 1; } } int main(int argc, char *argv[]) { int i; for (i = 0; i < 32; ++i) { printf("%d = ", i); //printbitssimple(i); printbits(i); printf("\n"); } return 0; } 

incluir

int main (void) {

 int a,i,k=1; int arr[32]; \\ taken an array of size 32 for(i=0;i <32;i++) { arr[i] = 0; \\initialised array elements to zero } printf("enter a number\n"); scanf("%d",&a); \\get input from the user for(i = 0;i < 32 ;i++) { if(a&k) \\bit wise and operation { arr[i]=1; } else { arr[i]=0; } k = k<<1; \\left shift by one place evry time } for(i = 31 ;i >= 0;i--) { printf("%d",arr[i]); \\print the array in reverse } return 0; 

}

// Esto es lo que hice cuando nuestro maestro nos pidió que hiciéramos esto

 int main (int argc, char *argv[]) { int number, i, size, mask; // our input,the counter,sizeofint,out mask size = sizeof(int); mask = 1<<(size*8-1); printf("Enter integer: "); scanf("%d", &number); printf("Integer is :\t%d 0x%X\n", number, number); printf("Bin format :\t"); for(i=0 ; i 

la forma más sencilla para mí de hacer esto (para una representación de 8 bits):

 #include  #include  #include  char *intToBinary(int z, int bit_length){ int div; int counter = 0; int counter_length = (int)pow(2, bit_length); char *bin_str = calloc(bit_length, sizeof(char)); for (int i=counter_length; i > 1; i=i/2, counter++) { div = z % i; div = div / (i / 2); sprintf(&bin_str[counter], "%i", div); } return bin_str; } int main(int argc, const char * argv[]) { for (int i = 0; i < 256; i++) { printf("%s\n", intToBinary(i, 8)); //8bit but you could do 16 bit as well } return 0; } 

Aquí hay otra solución que no requiere un char *.

 #include  #include  void print_int(int i) { int j = -1; while (++j < 32) putchar(i & (1 << j) ? '1' : '0'); putchar('\n'); } int main(void) { int i = -1; while (i < 6) print_int(i++); return (0); } 

O aquí para más legibilidad:

 #define GRN "\x1B[32;1m" #define NRM "\x1B[0m" void print_int(int i) { int j = -1; while (++j < 32) { if (i & (1 << j)) printf(GRN "1"); else printf(NRM "0"); } putchar('\n'); } 

Y aquí está el resultado:

 11111111111111111111111111111111 00000000000000000000000000000000 10000000000000000000000000000000 01000000000000000000000000000000 11000000000000000000000000000000 00100000000000000000000000000000 10100000000000000000000000000000 
 #include  #define BITS_SIZE 8 void int2Bin ( int a ) { int i = BITS_SIZE - 1; /* * Tests each bit and prints; starts with * the MSB */ for ( i; i >= 0; i-- ) { ( a & 1 << i ) ? printf ( "1" ) : printf ( "0" ); } return; } int main () { int d = 5; printf ( "Decinal: %d\n", d ); printf ( "Binary: " ); int2Bin ( d ); printf ( "\n" ); return 0; } 

No tan elegante, pero logra su objective y es muy fácil de entender:

 #include int binario(int x, int bits) { int matriz[bits]; int rest=0,i=0; float rest =0.0 ; for(int i=0;i<8;i++) { resto = x/2; rest = x%2; x = resto; if (rest>0) { matriz[i]=1; } else matriz[i]=0; } for(int j=bits-1;j>=0;j--) { printf("%d",matriz[j]); } printf("\n"); } int main() { int num,bits; bits = 8; for (int i = 0; i < 256; i++) { num = binario(i,bits); } return 0; } 

Aquí está mi solución. Crea una máscara, que comienza con todos los 0 y un 1 en el bit más a la izquierda, y la desplaza lógicamente hacia la derecha para cada bit en el entero de 32 bits asumido . Los bits se imprimen secuencialmente convirtiendo el valor del entero actualmente enmascarado en un valor booleano.

 void printBits(int val){ for(unsigned int mask = 0x80000000; mask; mask >>= 1){ printf("%d", !!(mask & val)); } } 
 void print_binary(int n) { if (n == 0 || n ==1) cout << n; else { print_binary(n >> 1); cout << (n & 0x1); } }