Распечатайте int в двоичном представлении, используя C

StackOverflow https://stackoverflow.com/questions/1024389

  •  06-07-2019
  •  | 
  •  

Вопрос

Я ищу функцию, позволяющую мне печатать двоичное представление 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. Код взят из здесь

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

Это было полезно?

Решение

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

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

Другие советы

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

  • завершить строку нулем
  • не используйте магические числа
  • проверьте возвращаемое значение 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;
}

Ваша строка не заканчивается нулем.Обязательно добавьте '\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()ing строку, которая возвращается.

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

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

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

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

это то, что я сделал для отображения интергера в виде бинарного кода, который разделен на 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++;
}

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

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

}

Две вещи:

<Ол>
  • Где вы положили NUL-символ? Я не вижу места, где установлено '\ 0' .
  • Int подписано, и 0xFF000000 будет интерпретироваться как отрицательное значение. Поэтому while (a > 0) будет сразу же ложным.
  • В стороне: функция malloc внутри уродлива. Как насчет предоставления буфера для int2bin?

    Пара вещей:

    int f = 32;
    int i = 1;
    do{
      str[--f] = i^a?'1':'0';
    }while(i<<1);
    
    • Это очень зависит от платформы, но, возможно, эта идея выше вызывает вас.
    • Почему бы не использовать memset (str, 0, 33), чтобы установить весь массив Char на 0?
    • Не забудьте освободить()!!!char* массив после вызова вашей функции!

    Две простые версии, закодированные здесь (воспроизведены с легким переформатированием).

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

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

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

    самый простой способ сделать это (для 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;
    }
    

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

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

    Не так элегантно, но достигает своей цели, и это очень легко понять:

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

    Вот мое решение. Он создает маску, начиная со всех 0 и 1 в крайнем левом бите, и логически сдвигает ее вправо для каждого бита в предполагаемом 32-разрядном целом числе. Биты последовательно печатаются путем преобразования значения текущего замаскированного целого числа в логическое значение.

    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);
        }
    }
    
    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top