Вывести int в двоичном представлении, используя C - PullRequest
23 голосов
/ 21 июня 2009

Я ищу функцию, позволяющую мне напечатать двоичное представление типа int. То, что я имею до сих пор, это;

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;

}

Но когда я звоню

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

Я получаю вывод как;

0000000000000000000000000000000000xtpYy (и несколько неизвестных символов.

Это недостаток функции или я печатаю адрес массива символов или что-то в этом роде? Извините, я просто не вижу, куда иду не так.

NB Код от здесь

РЕДАКТИРОВАТЬ: Это не домашнее задание К вашему сведению, я пытаюсь отладить чужие процедуры манипулирования изображениями на незнакомом языке. Однако, если это было помечено как домашнее задание, потому что это элементарная концепция, то честная игра.

Ответы [ 17 ]

30 голосов
/ 21 июня 2009

Вот еще один вариант, который более оптимизирован, когда вы передаете в выделенный буфер. Убедитесь, что это правильный размер.

// 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);
}
8 голосов
/ 21 июня 2009

Несколько предложений:

  • завершить нулевую строку
  • не используйте магические числа
  • проверьте возвращаемое значение malloc()
  • не приведите возвращаемое значение malloc()
  • используйте двоичные операции вместо арифметических, так как вас интересует двоичное представление
  • нет необходимости повторять цикл дважды

Вот код:

#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;
}
7 голосов
/ 21 июня 2009

Ваша строка не заканчивается нулем. Убедитесь, что вы добавили символ '\0' в конце строки; или вы можете выделить его с calloc вместо malloc, что обнулит память, возвращаемую вам.

Кстати, есть другие проблемы с этим кодом:

  • При использовании он выделяет память при вызове, оставляя вызывающего абонента ответственным за free() выделенную строку. Вы потеряете память, если просто позвоните в printf вызове.
  • Он делает два прохода над номером, что не нужно. Вы можете сделать все за один цикл.

Вот альтернативная реализация, которую вы можете использовать.

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

Использование:

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

Второй параметр - указатель на буфер, в котором вы хотите сохранить результирующую строку. Если у вас нет буфера, вы можете передать NULL, и int2bin запишет в буфер static и вернет это тебе. Преимущество этого по сравнению с оригинальной реализацией заключается в том, что вызывающей стороне не нужно беспокоиться о free() возвращаемой строке.

Недостатком является то, что существует только один статический буфер, поэтому последующие вызовы будут перезаписывать результаты предыдущих вызовов. Вы не можете сохранить результаты нескольких звонков для дальнейшего использования. Кроме того, это не потокобезопасно, то есть если вы вызываете функцию таким образом из разных потоков, они могут заглушить строки друг друга. Если это возможно, вам нужно будет передать в свой собственный буфер вместо передачи NULL, например:

char str[33];
int2bin(0xDEADBEEF, str);
puts(str);
1 голос
/ 30 января 2015
#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");
    }

}
1 голос
/ 12 января 2015

это то, что я сделал для отображения интергера в виде бинарного кода, он разделен на 4 бита:

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

это может быть немного большим, но я всегда пишу это таким образом (я надеюсь), что каждый может понять, что происходит. надеюсь, это помогло.

1 голос
/ 15 мая 2013

Вот простой алгоритм.

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;
        }
    }
0 голосов
/ 01 февраля 2017
#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;
}
0 голосов
/ 10 декабря 2016

Вот еще одно решение, которое не требует символа *.

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

Или здесь для большей читаемости:

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

А вот и вывод:

11111111111111111111111111111111
00000000000000000000000000000000
10000000000000000000000000000000
01000000000000000000000000000000
11000000000000000000000000000000
00100000000000000000000000000000
10100000000000000000000000000000
0 голосов
/ 01 декабря 2015

самый простой способ для меня сделать это (для 8-битного представления):

#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;
}
0 голосов
/ 08 января 2015

// Это то, что я сделал, когда наш учитель попросил нас сделать это

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);
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...