Wypisuje int w reprezentacji binarnej za pomocą C

Szukam funkcji, która pozwoli mi wydrukować binarną reprezentację int. To co mam do tej pory to;

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;

}

Ale kiedy wołam

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

I get output like;

0000000000000000000000000000000000000000xtpyy (i kilka nieznanych znaków.

Czy to wada funkcji, czy wypisuję adres tablicy znaków, czy coś? Przykro mi, ale nie widzę, co robię źle.

NB kod pochodzi z tutaj

EDIT: to nie jest zadanie domowe, próbuję debugować czyjeś procedury manipulacji obrazami w nieznanym języku. Jeśli jednak został oznaczony jako zadanie domowe, ponieważ jest to elementarna koncepcja, to fair play.

Author: Yu Hao, 2009-06-21

17 answers

Oto kolejna opcja, która jest bardziej zoptymalizowana tam, gdzie przekazujesz przydzielony bufor. Upewnij się, że to właściwy rozmiar.

// 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);
}
 30
Author: Adam Markowitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-30 19:43:09

Kilka sugestii:

  • null-Zakończ swój łańcuch
  • nie używaj magicznych liczb
  • sprawdź wartość zwracaną malloc()
  • nie rzucaj wartości zwracanej malloc()
  • użyj operacji binarnych zamiast arytmetycznych, ponieważ interesuje Cię reprezentacja binarna
  • nie ma potrzeby dwukrotnego zapętlania

Oto kod:

#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;
}
 8
Author: Christoph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-21 18:14:08

Twój łańcuch nie jest zakończony znakiem null. Upewnij się, że dodajesz znak '\0' na końcu łańcucha; lub możesz go przydzielić za pomocą calloc zamiast malloc, co spowoduje zerowanie pamięci, która zostanie zwrócona.

Przy okazji, są inne problemy z tym kodem:

  • używany, przydziela pamięć podczas wywoływania, pozostawiając wywołującego odpowiedzialnego za free()w przydzielonym łańcuchu. Wycieknie Ci pamięć, jeśli zadzwonisz na telefon.
  • daje dwa przejścia nad liczbą, co jest niepotrzebne. Możesz zrobić wszystko w jednej pętli.

Oto alternatywna implementacja, której możesz użyć.

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

Użycie:

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

Drugi parametr jest wskaźnikiem do bufora, w którym chcesz zapisać łańcuch wyników. Jeśli nie masz bufora, możesz przekazać NULL, a int2bin zapisze do bufora static i zwróci go tobie. Zaletą tego rozwiązania w stosunku do oryginalnej implementacji jest to, że rozmówca nie musi się martwić o free()ing sznurek, który zostanie zwrócony.

Minusem jest to, że istnieje tylko jeden bufor statyczny, więc kolejne wywołania nadpisują wyniki poprzednich wywołań. Nie można zapisać wyników z wielu wywołań do późniejszego wykorzystania. Ponadto, nie jest to threadsafe, co oznacza, że jeśli wywołasz funkcję w ten sposób z różnych wątków, mogą one blokować się nawzajem. Jeśli jest taka możliwość, musisz przekazać we własnym buforze zamiast przekazać NULL, w ten sposób:

char str[33];
int2bin(0xDEADBEEF, str);
puts(str);
 7
Author: John Kugelman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-21 18:42:55

Oto prosty algorytm.

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;
        }
    }
 1
Author: Luqman_Ahmad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-14 23:31:30

Oto, co zrobiłem, aby wyświetlić interger jako kod binarny, który jest rozdzielony na 4 bity:

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

To może być trochę duże, ale zawsze piszę to w taki sposób (mam nadzieję), że każdy może zrozumieć, co się dzieje. mam nadzieję, że to pomogło.

 1
Author: Kirito,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-12 15:25:54
#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
Author: amol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-30 03:39:57

Dwie rzeczy:

  1. Gdzie umieścić znak NUL? Nie widzę miejsca, gdzie '\0' jest ustawione.
  2. Int jest podpisany, a 0xFF000000 będzie interpretowane jako wartość ujemna. Więc while (a > 0) będzie natychmiast fałszywe.

Na bok: funkcja malloc wewnątrz jest brzydka. A co z dostarczeniem bufora do int2bin?

 0
Author: Markus Schnell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-21 17:49:25

Kilka rzeczy:

int f = 32;
int i = 1;
do{
  str[--f] = i^a?'1':'0';
}while(i<<1);
    Jest bardzo zależna od platformy, ale może ten pomysł da ci początek.
  • Dlaczego nie użyć memset (str, 0, 33) aby ustawić cała tablica znaków do 0?
  • nie zapomnij uwolnić()!!! char* tablica po wywołaniu funkcji!
 0
Author: merkuro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-21 17:57:35

Dwie proste wersje zakodowane Tutaj (odtworzone z łagodnym formatowaniem).

#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;
}
 0
Author: nik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-21 17:57:37

Include

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;

}

 0
Author: Anil Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-04 12:54:28

/ / to właśnie zrobiłem, gdy nasz nauczyciel poprosił nas o to

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);
} 
 0
Author: Ioannis Vogiatzis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-08 14:43:43

Najprostszy sposób dla mnie (dla reprezentacji 8bitowej):

#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
Author: KoSv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-01 13:23:19

Oto inne rozwiązanie, które nie wymaga znaku*.

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

Lub tutaj dla większej czytelności:

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

A oto wyjście:

11111111111111111111111111111111
00000000000000000000000000000000
10000000000000000000000000000000
01000000000000000000000000000000
11000000000000000000000000000000
00100000000000000000000000000000
10100000000000000000000000000000
 0
Author: Sequoya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-10 03:12:43
#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
Author: aldo núñez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-01 17:52:33

Nie tak eleganckie, ale realizuje swój cel i jest to bardzo łatwe do zrozumienia:

#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
Author: Michelangelo Machado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-02 23:21:04

Oto moje rozwiązanie. Tworzy maskę, zaczynającą się od wszystkich 0 i 1 w lewym bitie, i logicznie przesuwa ją w prawo dla każdego bitu założonego 32-bitowej liczby całkowitej. Bity są kolejno drukowane przez zamianę wartości aktualnie zamaskowanej liczby całkowitej na wartość logiczną.

void printBits(int val){
    for(unsigned int mask = 0x80000000; mask; mask >>= 1){
         printf("%d", !!(mask & val));
    }
}
 0
Author: Rosemary Fortanely,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-11 04:53:30
void print_binary(int n) {
    if (n == 0 || n ==1) 
        cout << n;
    else {
        print_binary(n >> 1);
        cout << (n & 0x1);
    }
}
 -1
Author: sean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-28 23:09:38