web-dev-qa-db-fra.com

Imprimer un int en représentation binaire en utilisant C

Je recherche une fonction pour pouvoir imprimer la représentation binaire d'un int. Ce que j'ai jusqu'ici est;

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;

}

Mais quand j'appelle

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

Je reçois la sortie comme;

00000000000000000000000000000000000000xtpYy (Et un tas de caractères inconnus.

Est-ce une faille dans la fonction ou est-ce que j'imprime l'adresse du tableau de caractères ou quelque chose? Désolé, je ne vois pas où je vais mal.

NB Le code est de ici

EDIT: Ce n'est pas un devoir FYI, j'essaye de déboguer les routines de manipulation d'images de quelqu'un d'autre dans un langage inconnu. Si toutefois c'est considéré comme un devoir parce que c'est un concept élémentaire, alors fair-play.

23
gav

Voici une autre option plus optimisée dans laquelle vous passez dans la mémoire tampon allouée. Assurez-vous que c'est la bonne taille.

// 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
Adam Markowitz

Quelques suggestions:

  • NULL Terminez votre chaîne
  • n'utilisez pas de nombres magiques
  • vérifier la valeur de retour de malloc()
  • ne lance pas la valeur de retour de malloc()
  • utilisez des opérations binaires au lieu d'opérations arithmétiques car la représentation binaire vous intéresse
  • il n'y a pas besoin de boucler deux fois

Voici le code:

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

Votre chaîne n'est pas terminée par un zéro. Assurez-vous d’ajouter un caractère '\0' à la fin de la chaîne; ou, vous pouvez l'allouer avec calloc au lieu de malloc, ce qui mettra à zéro la mémoire qui vous est rendue.

À propos, il y a d'autres problèmes avec ce code:

  • Tel qu'utilisé, il alloue de la mémoire lorsque vous l'appelez, laissant l'appelant responsable de free()ing la chaîne allouée. Vous perdrez de la mémoire si vous l'appelez simplement dans un appel printf.
  • Il fait deux passages sur le nombre, ce qui est inutile. Vous pouvez tout faire en une seule boucle.

Voici une autre implémentation que vous pourriez utiliser.

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

Usage:

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

Le deuxième paramètre est un pointeur sur un tampon dans lequel vous voulez stocker la chaîne de résultat. Si vous ne disposez pas de tampon, vous pouvez passer NULL et int2bin écrira dans un tampon static et vous le retournera. L'avantage de cela par rapport à l'implémentation d'origine est que l'appelant n'a pas à s'inquiéter de free()ing la chaîne qui est renvoyée.

L'inconvénient est qu'il n'y a qu'un seul tampon statique afin que les appels suivants écrasent les résultats des appels précédents. Vous ne pouvez pas enregistrer les résultats de plusieurs appels pour une utilisation ultérieure. En outre, il n’est pas threadsafe, c’est-à-dire que si vous appelez la fonction de cette manière à partir de différents threads, elles pourraient chevaucher les chaînes de l’autre. Si c'est une possibilité, vous devrez passer votre propre tampon au lieu de passer NULL, comme ceci:

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

c’est ce que j’ai fait pour afficher un nombre entier sous forme de code binairy; il est séparé par 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++;
}

ça pourrait être un peu gros mais je l'écris toujours d'une manière (j'espère) pour que tout le monde puisse comprendre ce qui se passe. espérons que cela a aidé.

1
Kirito

Voici un algorithme simple. 

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
Luqman_Ahmad
#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
amol
#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
aldo núñez

la manière la plus simple pour moi de faire cela (pour une représentation 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;
}
0
KoSv

Un certain nombre de choses:

int f = 32;
int i = 1;
do{
  str[--f] = i^a?'1':'0';
}while(i<<1);
  • Cela dépend fortement de la plate-forme, mais Peut-être que cette idée ci-dessus vous permet de démarrer.
  • Pourquoi ne pas utiliser memset (str, 0, 33) pour définir Tout le tableau de caractères à 0?
  • N'oubliez pas de libérer () !!! le tableau char * après votre appel de fonction!
0
merkuro

Voici ma solution. Il crée un masque, commençant par tous les 0 et le 1 du bit le plus à gauche, et le décale logiquement vers la droite pour chaque bit du entier 32 bits assumé. Les bits sont imprimés séquentiellement en convertissant la valeur du nombre entier masqué en une valeur booléenne.

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

Deux choses:

  1. Où mettez-vous le personnage NUL? Je ne peux pas voir un endroit où '\0' est défini.
  2. Int est signé et 0xFF000000 serait interprété comme une valeur négative. Donc while (a > 0) sera faux immédiatement.

A part: la fonction malloc à l'intérieur est moche. Qu'en est-il de fournir un tampon à int2bin?

0
Markus Schnell
#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;
}
0
Anil Kumar

Deux versions simples codées ici (reproduites avec un reformatage doux).

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

Voici une autre solution qui ne nécessite pas de caractère *.

#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 ici pour plus de lisibilité:

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

Et voici la sortie:

11111111111111111111111111111111
00000000000000000000000000000000
10000000000000000000000000000000
01000000000000000000000000000000
11000000000000000000000000000000
00100000000000000000000000000000
10100000000000000000000000000000
0
Sequoya

// C'est ce que j'ai fait quand notre professeur nous a demandé de le faire

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
Ioannis Vogiatzis

Pas si élégant, mais atteint votre objectif et il est très facile à comprendre:

#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