web-dev-qa-db-fra.com

Décimal à binaire

J'ai un nombre que je voudrais convertir en binaire (à partir de décimal) en C.

Je voudrais que mon binaire soit toujours sur 5 bits (la décimale ne dépassera jamais 31). J'ai déjà une fonction qui le fait manuellement en le divisant, mais il est difficile de la régler à 5 bits.

Y a-t-il un moyen plus facile? Peut-être en utilisant bitwise shift?

J'aimerais aussi que le binaire soit représenté dans un char *

14
darksky

Voici une solution élégante:

void getBin(int num, char *str)
{
  *(str+5) = '\0';
  int mask = 0x10 << 1;
  while(mask >>= 1)
    *str++ = !!(mask & num) + '0';
}

Ici, nous commençons par nous assurer que la chaîne se termine par un caractère nul. Ensuite, nous créons un masque avec un seul masque (c’est le masque que vous attendez, décalé une fois vers la gauche pour prendre en compte le décalage de la première exécution conditionnelle). Chaque fois dans la boucle, le masque est décalé d'un endroit vers la droite, puis le caractère correspondant est défini sur un '1' ou un '0' (le !! garantit que nous ajoutons un 0 ou un 1 à '0' ). Enfin, lorsque le 1 dans le masque est décalé hors du nombre, la boucle while se termine.

Pour le tester, utilisez ce qui suit:

int main()
{
  char str[6];
  getBin(10, str);
  printf("%s\n", str);
  return 0;
}
19
Aaron Dufour

Si vous n'avez pas besoin de zéros au début, vous pouvez simplement utiliser itoa (valeur, chaîne de sortie, base)

Par exemple

char s[9];
itoa(10, s, 2);
printf("%s\n", s);

va imprimer

1010

Sinon, vous pouvez simplement écrire une fonction très simple.

void tobin5str(int value, char* output)
{
    int i;
    output[5] = '\0';
    for (i = 4; i >= 0; --i, value >>= 1)
    {
        output[i] = (value & 1) + '0';
    }
}

int main()
{
    char s[6];
    tobin5str(10, s);
    printf("%s\n", s);
    return 0;
}

va imprimer

01010

Une approche plus générique peut être une fonction qui vous demande combien de bits convertir.

void tobinstr(int value, int bitsCount, char* output)
{
    int i;
    output[bitsCount] = '\0';
    for (i = bitsCount - 1; i >= 0; --i, value >>= 1)
    {
        output[i] = (value & 1) + '0';
    }
}

Bien sûr, bitsCount doit avoir une valeur comprise entre 1 et 32, et la chaîne de mémoire tampon doit être allouée à au moins bitsCount + 1 caractères.

15
Salvatore Previti

Une approche est la suivante:

unsigned int x = 30;

char bits[] = "00000";

bits[4] = (x & 1) + '0';
x >>= 1;
bits[3] = (x & 1) + '0';
x >>= 1;
bits[2] = (x & 1) + '0';
x >>= 1;
bits[1] = (x & 1) + '0';
x >>= 1;
bits[0] = x + '0';

Probablement pas l'approche la plus élégante ...

4
Mysticial

Pour 31 valeurs, au lieu de faire malloc pour allouer une chaîne, suivie de la manipulation de bits pour la remplir, vous pouvez simplement utiliser une table de correspondance.

static const char *bitstrings[] = {
    "00000", "00001", "00010", … "11111"
};

Ensuite, votre conversion est aussi simple que return bitstrings[i]. Si vous faites cela souvent, cela sera plus rapide (en évitant malloc).

Sinon, vous n'avez pas vraiment besoin de décalage (sauf pour faciliter l'écriture de vos constantes); vous pouvez simplement utiliser bit-and:

char *bits = malloc(6);
bits[0] = (i & (1<<4)) ? '1' : '0';   /* you can also just write out the bit values, but the */
bits[1] = (i & (1<<3)) ? '1' : '0';   /* compiler should be able to optimize a constant!     */
⋮
bits[6] = 0; /* null-terminate string*/

Il y a une (peut-être) micro-optimisation que vous pouvez faire si vous supposez ASCII, en utilisant addition. Vous pouvez également utiliser une boucle ici, mais il me fallait deux lignes pour le commentaire :-P. Du point de vue de la performance, aucun des deux n’importera Tout le temps est passé à Malloc.

1
derobert

Vous pouvez toujours diviser et régler le curseur sur 5 bits (ceci a pour effet d'ajouter 8 bits, car imprimer un caractère tel que A correspond au nombre 65)

#include <stdio.h>
#include <math.h>
void main(){
int binary[8], number, i; //for 5 bits use binary[5]
do{
printf("input a number: ");
scanf("%d",&number);
fflush(stdin);
}while(number>256 || number <0); //for 5 bits... 31 use number>31 || number <0
for (i=0; i<=7; i++)  // for 5 bits use i<=4
    {
    binary[i]=number%2;
    number = number/2;
    }
for (i=7; i >=0; i--)  //for 5 bits use i=4
    printf("%d", binary[i]);
number=0; // its allready 0.
for (i=0; i<=7; i++)  //for 5 bits use i<=4
    {
    number=number+binary[i]*pow(2,i);
    }
printf("\n%c",number);
}
#include <stdio.h>
#include <string.h>

char numstr[9024];
int i = 0;

void format(int n, int base);
void printreverse(char *s);

int main()
{
     int testnum = 312;    // some random test number
     format(testnum, 2);   // 2 for binary
     printreverse(numstr);
     putchar('\n');

     return 0;
}

void format(int n, int base)
{
    if (n > 0) {
        char tmp = (n % base) + '0';
        numstr[i++] = tmp;

        // If we put this above other two we don't need printreverse,
        // But then we will have unwanted results in other places of numstr if we can't reset it

        format(n/base, base); 
    } else
        numstr[i] = '\0'; // terminating character
}

void printreverse(char *s)
{
    long len = strlen(s);
    while (len-->0)
        putchar(s[len]);
}
0
Pramod

Ma prise

char* to_bitstring(uint32_t val, char buffer[], int size) {
    buffer[--size] = 0;
    while (size > 0) {
        buffer[--size] = (val % 2 ? '1' : '0');
        val = val >> 1;
    }

    return buffer; /* convenience */
}

Ceci écrira les caractères SIZE dans BUFFER:

char buffer[17];
printf("%s\n", to_bitstring(42, buffer, sizeof(buffer)));

Et imprimera:

0000000000101010
0
Hugo

Puisque vous ne travaillez qu'avec 5 bits, pourquoi ne pas utiliser une table de correspondance? Quelque chose comme ce qui suit:

/* Convert nstr to a number (decimal) and put a string representation of the
 * lowest 5 bits in dest (which must be at least 6 chars long) */
void getBinStr(char *dest, const char *nstr)
{
  char *lkup[32] = { 
    "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111",
    "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111",
    "10000", "10001", "10010", "10011", "10100", "10101", "10110", "10111",
    "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111" };
  strcpy(dest, lkup[atoi(nstr) & 0x1f]);
}

Ou un interrupteur:

void getBinStr(char *dest, const char *nstr)
{
  switch (atoi(nstr)) {
    case 31:  strcpy(dest,"11111"); break;
    case 30:  strcpy(dest,"11110"); break;
    ...
    case 1:   strcpy(dest,"00001"); break;
    case 0:   strcpy(dest,"00000"); break;
    default:  strcpy(dest,"error");
  }
}

Ou si cela semble trop long, peut-être quelque chose comme ceci:

void getBinStr(char *dest, const char *nstr)
{
  unsigned x = atoi(nstr);
  dest[0] = (x & 0x10) ? '1' : '0';
  dest[1] = (x & 0x08) ? '1' : '0';
  dest[2] = (x & 0x04) ? '1' : '0';
  dest[3] = (x & 0x02) ? '1' : '0';
  dest[4] = (x & 0x01) ? '1' : '0';
  dest[5] = '\0';
}

Je préférerais normalement l’un des deux premiers, mais le dernier pourrait être meilleur si, pour une raison quelconque, les autres sont trop volumineux (comme du code pour un petit microcontrôleur).

Tout cela suppose que vous voulez que le résultat soit rempli de zéros à 5 bits.

0
Dmitri
#include<stdio.h>

int mask = 1;
void decToBi(int);

void decToBi(int n){
    for(int j=15;j>=0;j--){
        int result;
        result = n & (mask<<j);
        if(result)
            printf("1");
        else
            printf("0");
    }    
}    
int main(){
    int n;
    scanf("%d",&n);
    decToBi(n);
    printf("\n");
return 0;
}

J'espère que cela t'aides

0
#include "stdio.h"
#include "conio.h"

int main(void)
{
int i, d , n = 1;
int store[10];

printf("Please enter a number to be converted to binary:\n");
scanf("%d",&d);

for (i=0;i<8 ;i++ )
  store[i] = 0;

i = 0;

do{
if(d & n ){
    n <<= 1;  //10
    store[i] = 1;
    i++;
}
else {
    n <<= 1;
    store[i] = 0;
    i++;
}

}while(n <= d);

printf("\n");
for (i=7;i>=0 ;i-- ){
  printf("%d",store[i]);
if(i == 4)
    printf(" ");
}
printf("\n");
return 0;
}
0
Ahmed Hassan
int main() {
    int n,c,k;
    printf("Enter_an_integer_in_decimal_number_system:_");
    scanf("%d",&n);
    printf("%d_in_binary_number_system_is:_", n);
    for (c = n; c > 0; c = c/2) {
        k = c%2;
        k = (k>0)? printf("1"):printf("0");
    }
    getch();
    return 0;
}
0
Mohmed AbdAllah

Voici le programme C permettant de convertir des nombres décimaux en fichiers binaires à l'aide d'opérateur au niveau des bits, avec tout décimal pris en charge par le système et ne contenant que la mémoire requise

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char **argv) 
{
    int n, t = 0;
    char *bin, b[2] = ""; 
    scanf("%d", &n);
    bin = (char*)malloc(sizeof(char) + 2);
    while (n != 0)
    {
        t = n >> 1;
        t = t << 1;
        t = n - t;
        n = n >> 1;
        itoa(t, b, 10);
        bin = realloc((char*)bin, sizeof(char) + 1);
        strcat(bin, b);
    }
    strrev(bin);
    printf("\n%s\n", bin);

    return 0 ;
}
0
Rahul Raina