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 me llaman

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

Puedo obtener una salida como;

0000000000000000000000000000000000xtpyy (Y un montón de personajes desconocidos.

Es un defecto en la función o soy yo la impresión de que la dirección de la matriz de caracteres o algo? Lo siento, no puedo ver donde estoy pasando mal.

NOTA: El código es de aquí

EDIT: no Es tarea para tu INFORMACIÓN, estoy tratando de depuración de alguien manipulación de la imagen de rutinas en un idioma desconocido. Si, sin embargo, ha sido etiquetado como tarea para casa porque es un elemental concepto, a continuación, juego limpio.

  • Los caracteres al azar están ahí porque no añadir un byte NULL al final de la cadena. (‘\0’) Este carácter indica el final de la cadena, de lo contrario printf va a seguir buscando hasta que encuentra uno, en este caso mirando a través de lo desconocido de la memoria.
InformationsquelleAutor gav | 2009-06-21

17 Comentarios

  1. 30

    Aquí es otra opción que está más optimizado donde se pasa en su 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] = '
    //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);
    }
    '
    ; int2bin(0xFF000000, buffer, BUF_SIZE - 1); printf("a = %s", buffer); }
    • uno de los más código tweak que (en mi humilde opinión) hace más legible es el uso de (a & (1<<i)) en lugar de (a & 1), seguido por el (a >>= 1) para verificar la i-esima poco. De esa manera el cuerpo del bucle contiene sólo la lógica, no las declaraciones necesarias para la actualización de los valores.
    • Esto hizo que el truco, muchas gracias! Puedo volver a esto realmente malo depuración de ahora!
    • Usted dice que «se supone little endian», pero las operaciones con números enteros son endian independiente.
    • Usted necesita paréntesis en su comparación: ((a & 1) == 0. De lo contrario, siempre se imprime ‘1’. Yo también prefiero esta: *buffer– = (a & 1) + ‘0’
    • ¿Qué + ‘0’ parte hacer?
    • el (a&1) comprueba el byte más a la derecha de una si es 1. si es entonces que la operación devolverá 1. ‘0’ es el código ascii para la letra 0, que es de 48 en decimal. ‘1’ es el código ascii para la letra 1 que es de 49 en decimal. así que esta adición cuando el último bit es 0 se eval a 48, que imprime un 0, mientras que cuando se es 1 se eval a 49 que imprime 1.
    • BUF_SIZE se establece en el 33, pero esta basado en la suposición de que sizeof(int) igual a 4. Dado que este no es necesariamente el caso, una definición más precisa sería: sizeof(int) * 8 + 1
    • Yo sugeriría que la unión de la for bucle el valor de inicio para la buf_size como este: for (i = buf_size-2; i >= 0; i--) { ... }. De lo contrario, el código es inservible si BUF_SIZE está ajustado a algo distinto de 33.

  2. 8

    Un par de sugerencias:

    • terminar null su cadena de
    • no usar la magia de los números de
    • comprobar el valor devuelto de malloc()
    • no lanzas el valor de retorno de malloc()
    • uso de las operaciones binarias en lugar de la aritmética, como el que usted está interesado en la representación binaria
    • no hay necesidad de bucle doble

    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;
    }
  3. 7

    Su cadena no está terminada en null. Asegúrese de añadir un '\0' carácter al final de la cadena; o, usted podría asignar con calloc en lugar de malloc, que pondrá a cero la memoria que es devuelta a usted.

    Por el camino, hay otros problemas con este código:

    • Como se usa, asigna memoria al acceder a ella, dejando a la persona que llama responsables de free()ción de la cadena asignado. Tendrás la pérdida de memoria si usted acaba de llamar en un printf llamada.
    • Hace dos pases sobre el número, el cual es innecesario. Usted puede hacer todo en un bucle.

    Aquí está una implementación alternativa que se puede utilizar.

    #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] = '
    #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
    }
    '
    ; return buf; #undef BITS }

    Uso:

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

    El segundo parámetro es un puntero a un búfer que desea almacenar el resultado de la cuerda. Si usted no tiene un buffer que puede pasar NULL y int2bin va a escribir a un static de amortiguamiento y de regreso a ti. La ventaja de este sobre la implementación original es que la persona que llama no tiene que preocuparse acerca de free()ción de la cadena que se obtiene regresó.

    Una desventaja es que sólo hay un búfer estático para las llamadas posteriores se sobrescribirán los resultados de convocatorias anteriores. No se podía guardar los resultados de múltiples llamadas para su uso posterior. Además, no es seguro para subprocesos, es decir, si se llama a la función de esta manera desde diferentes subprocesos que podría darle una paliza a cada una de las otras cadenas. Si que es una posibilidad que tendremos que pasar en su propio búfer en lugar de pasar NULL, así:

    char str[33];
    int2bin(0xDEADBEEF, str);
    puts(str);
    • El uso de un buffer estático como el valor de retorno no es seguro para subprocesos y también no se permite para guardar el resultado para su posterior si varias llamadas están involucrados.
    • Buenos puntos. Reescrito para explicar esas advertencias.
  4. 1

    Aquí es un simple algoritmo.

    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;
            }
        }
  5. 1

    esto es lo que he hecho para mostrar un interger como un binairy código de la que está separada 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 escribo de una manera (espero) que todo el mundo puede entender lo que está pasando. espero que esta ayuda.

    • cajero en la última línea debe ser contador(i transleted para que todo el mundo puede entender)
  6. 1
    #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");
        }
    
    }
  7. 0

    Dos cosas:

    1. ¿Dónde se coloca el caracter NUL? Yo no puedo ver un lugar donde '\0' se establece.
    2. Int está firmado, y 0xFF000000 sería interpretado como un valor negativo. Así while (a > 0) será falsa inmediatamente.

    De lado: La función malloc en el interior es feo. Lo que trata de proporcionar un buffer para int2bin?

  8. 0

    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 anteriormente le ayudará a comenzar.
    • ¿Por qué no utilizar memset(str, 0, 33) para el conjunto de
      la totalidad de la matriz de char a 0?
    • No olvides liberar()!!! char*
      matriz después de la llamada a la función!
  9. 0

    Dos versiones simples codificado aquí (reproducido con leve formato).

    #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;
    }
  10. 0

    //Esto es lo que hice, cuando nuestro profesor nos pidió hacer este

    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);
    } 
  11. 0

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

    #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;
    }
  12. 0

    Aquí hay otra solución que no requiere de 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 obtener 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
  13. 0
    #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;
    }
  14. 0

    No tan elegante, pero logra 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;
    }
  15. 0

    Aquí está mi solución. Crea una máscara, comenzando con todos 0 y un 1 en el extremo izquierdo de bits, y lógicamente se mueve a la derecha para cada bit en el supone entero de 32 bits. Los bits son secuencialmente impreso por convertir el valor del enmascarado entero en un valor booleano.

    void printBits(int val){
        for(unsigned int mask = 0x80000000; mask; mask >>= 1){
             printf("%d", !!(mask & val));
        }
    }
  16. 0
    #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;
    }
  17. -1
    void print_binary(int n) {
        if (n == 0 || n ==1) 
            cout << n;
        else {
            print_binary(n >> 1);
            cout << (n & 0x1);
        }
    }
    • lo siento, la ‘cout << n & 0 x 1)’ también debe ser parte de la otra parte. maldito formato ..
    • La pregunta fue marcada como C, no C++. También, si n es negativo, el resultado es indefinido. Por último, no es de formato (C/C++ no se preocupa por el formato de por sí), es la falta de paréntesis que deben grupo de dos estados en uno solo (he agregado para usted).

Dejar respuesta

Please enter your comment!
Please enter your name here