Pregunta

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

Me sale como;

  

0000000000000000000000000000000000xtpYy (Y un montón de caracteres desconocidos.

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

NB El código es de aquí

EDITAR: No es tarea para tu 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.

¿Fue útil?

Solución

Aquí hay otra opción que está más optimizada cuando pasas el búfer asignado. Asegúrese 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 i.e.  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);
}

Otros consejos

Algunas sugerencias:

  • termina en nulo su cadena
  • no uses números mágicos
  • verifique el valor de retorno de malloc()
  • no arroje el valor de retorno de malloc()
  • use operaciones binarias en lugar de aritméticas, ya que está interesado en la representación binaria
  • no hay necesidad de repetir dos veces

Aquí está el código:

#include <stdlib.h>
#include <limits.h>

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 en lugar de malloc , que pondrá a cero la memoria que se le devuelve.

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

  • Como se usa, asigna memoria cuando lo llama, dejando a la persona que llama responsable de free () la cadena asignada. Perderá memoria si solo lo llama en una llamada printf .
  • Hace dos pases sobre el número, lo cual es innecesario. Puedes hacer todo en un bucle.

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

#include <stdlib.h>
#include <limits.h>

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 y int2bin escribir en un búfer static y devolvérselo. La ventaja de esto sobre la implementación original es que la persona que llama no tiene que preocuparse por free () que ingiere la cadena que se devuelve.

Una desventaja es que solo hay un búfer estático, por lo que las llamadas posteriores sobrescribirán los resultados de las llamadas anteriores. No pudo guardar los resultados de varias llamadas para su uso posterior. Además, no es seguro para subprocesos, lo que significa que si llama a la función de esta manera desde diferentes subprocesos, podrían golpearse las cadenas entre sí. Si es una posibilidad, deberá pasar su propio búfer en lugar de pasar NULL , de esta manera:

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 número entero 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) para que todos puedan entender lo que está sucediendo. Espero que esto haya ayudado.

#include<stdio.h>
//#include<conio.h>  // 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 se establezca '\ 0' .
  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 búfer 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 ayude a comenzar.
  • ¿Por qué no usar memset (str, 0, 33) para establecer todo el conjunto de caracteres a 0?
  • No te olvides de liberar () !!! el char * matriz después de su llamada a la función!

Dos versiones simples codificadas aquí (reproducido con un reformateo leve).

#include <stdio.h>

/* 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;
}

// 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<size*8 ;++i ) {
        if ((i % 4 == 0) && (i != 0))  {
            printf(" ");
        }

        printf("%u",number&mask ? 1 : 0);

        number = number<<1;
    }
    printf("\n");

    return (0);
} 

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

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

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 <stdio.h>
#include <stdlib.h>

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 <stdio.h>

#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 es tan elegante, pero cumple su objetivo y es muy fácil de entender:

#include<stdio.h>

int binario(int x, int bits)
{
    int matriz[bits];
    int resto=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 a la derecha para cada bit en el entero supuesto de 32 bits. 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));
    }
}
#include <stdio.h>
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;
}
void print_binary(int n) {
    if (n == 0 || n ==1) 
        cout << n;
    else {
        print_binary(n >> 1);
        cout << (n & 0x1);
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top