Pergunta

Eu estou procurando uma função para permitir-me para imprimir a representação binária de um int. O que eu tenho até agora é;

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;

}

Mas quando eu chamo

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

Eu recebo uma saída como;

0000000000000000000000000000000000xtpYy (e um monte de personagens desconhecidos.

É uma falha na função ou estou imprimindo o endereço da matriz de caracteres ou algo assim? Desculpe, eu simplesmente não consigo ver onde estou indo errado.

NB O código é de aqui

EDIT: Não é lição de casa FYI, eu estou tentando rotinas de manipulação de imagem de depuração de outra pessoa em uma língua estranha. Se, contudo, tem sido marcado como lição de casa porque é um conceito fundamental em seguida, o jogo justo.

Foi útil?

Solução

Aqui está uma outra opção que é mais otimizado, onde você passar em seu buffer alocado. Certifique-se de que é o tamanho correto.

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

Outras dicas

Algumas sugestões:

  • nulo encerrar sua seqüência
  • não use números mágicos
  • verificar o valor de retorno de malloc()
  • não converter o valor de retorno de malloc()
  • usar operações binárias em vez dos aritméticas como você está interessado na representação binária
  • não há necessidade para looping duas vezes

Aqui está o 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;
}

A seqüência não é terminada em nulo. Certifique-se de adicionar um caractere '\0' no final da string; Ou, você pode alocá-lo com calloc vez de malloc, que irá zerar a memória que é devolvido a você.

A propósito, há outros problemas com este código:

  • Como usado, ele aloca memória quando você chamá-lo, deixando o interlocutor responsável por free()ing a string alocada. Você vai vazar memória se você chamá-lo numa chamada printf.
  • Faz duas passagens sobre o número, o que é desnecessário. Você pode fazer tudo em um loop.

Aqui está uma implementação alternativa, você poderia 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));

O segundo parâmetro é um ponteiro para um buffer que deseja armazenar a string de resultado. Se você não tem um buffer você pode passar NULL e int2bin vai escrever para um buffer static e retorno que para você. A vantagem deste sobre a implementação original é que o chamador não precisa se preocupar com free()ing a string que será retornado.

A desvantagem é que há apenas um buffer estático assim chamadas subsequentes irá substituir os resultados de chamadas anteriores. Você não pode salvar os resultados de várias chamadas para uso posterior. Além disso, não é threadsafe, ou seja, se você chamar a função desta forma de diferentes tópicos que poderiam espancar cordas do outro. Se isso é uma possibilidade que você precisa para passar em seu próprio tampão em vez de passar NULL, assim:

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

Aqui está um algoritmo simples.

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

isto é o que eu fiz para exibir um inteiro como um código binairy é 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++;
}

poderia ser um pouco grande, mas eu sempre escrevê-lo de uma maneira (espero) que todos podem entender o que está acontecendo. espero que isso ajudou.

#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");
    }

}

Duas coisas:

  1. Onde você coloca o personagem NUL? Eu não posso ver um lugar onde '\0' está definido.
  2. Int é assinado, e 0xFF000000 seria interpretado como um valor negativo. Então while (a > 0) será falso imediatamente.

Além: A função malloc interior é feio. O que sobre o fornecimento de um buffer para int2bin?

Um par de coisas:

int f = 32;
int i = 1;
do{
  str[--f] = i^a?'1':'0';
}while(i<<1);
  • É altamente dependente de plataforma, mas talvez esta idéia acima é uma introdução.
  • Por que não usar memset (str, 0, 33) para definir todo o caractere matriz para 0?
  • Não se esqueça de liberar () !!! char * matriz após a sua chamada de função!

Duas versões simples codificado aqui (reproduzido com reformatação 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;
}

// Isto é o que eu fiz quando o nosso professor nos pediu para fazer isso

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);
} 

a maneira mais simples para mim fazer isso (para uma representação 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;
}

Aqui é outra solução que não requer um 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);
}

Ou aqui para mais legibilidade:

#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');
}

E aqui está a saída:

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

Não é tão elegante, mas cumpre seu objetivo e é muito 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;
}

Aqui está a minha solução. Ele cria uma máscara, começando com todos os 0 e um 1 no bit mais à esquerda, e logicamente desloca certa para cada bit no 32-bit inteiro assumido. Os bits são sequencialmente impresso, convertendo o valor do inteiro actualmente mascarados para um 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top