Подтвердить что ты не робот

Печать int в двоичном представлении с использованием C

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

Я получаю вывод вроде:

00000000000000000000000000000000000000ppYy (И куча неизвестных символов.

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

NB Код здесь

EDIT: Это не домашнее задание FYI, я пытаюсь отлаживать другие процедуры манипуляции изображениями на незнакомом языке. Если же он был помечен как домашнее задание, потому что это элементарное понятие, то честная игра.

4b9b3361

Ответ 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);
}

Ответ 2

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

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

Ответ 3

Строка не завершена нулевым символом. Убедитесь, что вы добавили символ '\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);

Ответ 4

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

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

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

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

Ответ 6

#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

Несколько вещей:

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

Ответ 8

Две вещи:

  • Где вы помещаете символ NUL? Я не вижу места, где установлен '\0'.
  • Int подписан, а 0xFF000000 будет интерпретироваться как отрицательное значение. Таким образом, while (a > 0) будет немедленно ошибочным.

Кроме того: функция malloc внутри является уродливой. Как насчет предоставления буфера для int2bin?

Ответ 9

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

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

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

Ответ 11

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

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

Ответ 12

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

Ответ 13

Вот еще одно решение, для которого не требуется 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);
}

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

#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

Ответ 14

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

Ответ 15

Не так изящно, но выполняет свою цель, и это очень легко понять:

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

Ответ 16

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

void printBits(int val){
    for(unsigned int mask = 0x80000000; mask; mask >>= 1){
         printf("%d", !!(mask & val));
    }
}

Ответ 17

void print_binary(int n) {
    if (n == 0 || n ==1) 
        cout << n;
    else {
        print_binary(n >> 1);
        cout << (n & 0x1);
    }
}