Existe-t-il un convertisseur printf pour imprimer en format binaire?

je peux imprimer avec printf comme un nombre hexadécimal ou octal. Existe-t-il une balise de format à imprimer en binaire, ou base arbitraire?

je dirige gcc.

printf("%d %x %on", 10, 10, 10); //prints "10 A 12n"
print("%bn", 10); // prints "%bn"
347
demandé sur Brian 2008-09-22 00:04:58

30 réponses

Hacky mais travaille pour moi:

#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
#define BYTE_TO_BINARY(byte)  \
  (byte & 0x80 ? '1' : '0'), \
  (byte & 0x40 ? '1' : '0'), \
  (byte & 0x20 ? '1' : '0'), \
  (byte & 0x10 ? '1' : '0'), \
  (byte & 0x08 ? '1' : '0'), \
  (byte & 0x04 ? '1' : '0'), \
  (byte & 0x02 ? '1' : '0'), \
  (byte & 0x01 ? '1' : '0') 
printf("Leading text "BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(byte));

pour les types à plusieurs octets

printf("m: "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n",
  BYTE_TO_BINARY(m>>8), BYTE_TO_BINARY(m));

vous avez besoin de toutes les citations supplémentaires malheureusement. Cette approche comporte les risques d'efficacité des macros (ne pas passer une fonction comme argument à BYTE_TO_BINARY ) mais évite les problèmes de mémoire et les invocations multiples de strcat dans certaines des autres propositions ici.

205
répondu William Whyte 2016-05-27 17:29:50

Print binaire pour tout type de données

//assumes little endian
void printBits(size_t const size, void const * const ptr)
{
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;
    int i, j;

    for (i=size-1;i>=0;i--)
    {
        for (j=7;j>=0;j--)
        {
            byte = (b[i] >> j) & 1;
            printf("%u", byte);
        }
    }
    puts("");
}

essai

int main(int argv, char* argc[])
{
        int i = 23;
        uint ui = UINT_MAX;
        float f = 23.45f;
        printBits(sizeof(i), &i);
        printBits(sizeof(ui), &ui);
        printBits(sizeof(f), &f);
        return 0;
}
192
répondu criptych 2016-05-05 14:09:14

voici un hack rapide pour démontrer les techniques pour faire ce que vous voulez.

#include <stdio.h>      /* printf */
#include <string.h>     /* strcat */
#include <stdlib.h>     /* strtol */

const char *byte_to_binary(int x)
{
    static char b[9];
    b[0] = '"151900920"';

    int z;
    for (z = 128; z > 0; z >>= 1)
    {
        strcat(b, ((x & z) == z) ? "1" : "0");
    }

    return b;
}

int main(void)
{
    {
        /* binary string to int */

        char *tmp;
        char *b = "0101";

        printf("%d\n", strtol(b, &tmp, 2));
    }

    {
        /* byte to binary string */

        printf("%s\n", byte_to_binary(5));
    }

    return 0;
}
148
répondu EvilTeach 2012-10-17 01:14:11

il n'y a pas de spécificateur de conversion binaire dans glibc normalement.

il est possible d'ajouter des types de conversion personnalisés à la famille de fonctions printf() dans glibc. Voir registrer_printf_function pour plus de détails. Vous pouvez ajouter une conversion %B personnalisée pour votre propre usage, si elle simplifie le code d'application pour le rendre disponible.

voici un exemple de la façon d'implémenter un format personnalisé printf dans la glibc.

76
répondu DGentry 2009-04-16 23:19:19

vous pouvez utiliser un petit tableau pour améliorer la vitesse 1 . Des techniques similaires sont utiles dans le monde embarqué, par exemple, pour inverser un octet:

const char *bit_rep[16] = {
    [ 0] = "0000", [ 1] = "0001", [ 2] = "0010", [ 3] = "0011",
    [ 4] = "0100", [ 5] = "0101", [ 6] = "0110", [ 7] = "0111",
    [ 8] = "1000", [ 9] = "1001", [10] = "1010", [11] = "1011",
    [12] = "1100", [13] = "1101", [14] = "1110", [15] = "1111",
};

void print_byte(uint8_t byte)
{
    printf("%s%s", bit_rep[byte >> 4], bit_rep[byte & 0x0F]);
}

1 je fais surtout référence aux applications intégrées où les optimiseurs ne sont pas aussi agressifs et où la différence de vitesse est visible.

21
répondu Shahbaz 2017-12-25 21:16:00

Voici une version de la fonction qui ne souffre pas de problèmes de réentrance ou des limites sur la taille / type de l'argument:

#define FMT_BUF_SIZE (CHAR_BIT*sizeof(uintmax_t)+1)
char *binary_fmt(uintmax_t x, char buf[static FMT_BUF_SIZE])
{
    char *s = buf + FMT_BUF_SIZE;
    *--s = 0;
    if (!x) *--s = '0';
    for(; x; x/=2) *--s = '0' + x%2;
    return s;
}

notez que ce code fonctionnerait aussi bien pour n'importe quelle base entre 2 et 10 si vous remplacez juste les 2 par la base désirée. Utilisation:

char tmp[FMT_BUF_SIZE];
printf("%s\n", binary_fmt(x, tmp));

x est toute expression intégrale.

16
répondu R.. 2011-01-29 21:34:05

basé sur la réponse de @William Whyte, c'est une macro qui fournit int8 , 16 , 32 & 64 versions, en réutilisant la macro INT8 pour éviter la répétition.

/* --- PRINTF_BYTE_TO_BINARY macro's --- */
#define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
#define PRINTF_BYTE_TO_BINARY_INT8(i)    \
    (((i) & 0x80ll) ? '1' : '0'), \
    (((i) & 0x40ll) ? '1' : '0'), \
    (((i) & 0x20ll) ? '1' : '0'), \
    (((i) & 0x10ll) ? '1' : '0'), \
    (((i) & 0x08ll) ? '1' : '0'), \
    (((i) & 0x04ll) ? '1' : '0'), \
    (((i) & 0x02ll) ? '1' : '0'), \
    (((i) & 0x01ll) ? '1' : '0')

#define PRINTF_BINARY_PATTERN_INT16 \
    PRINTF_BINARY_PATTERN_INT8              PRINTF_BINARY_PATTERN_INT8
#define PRINTF_BYTE_TO_BINARY_INT16(i) \
    PRINTF_BYTE_TO_BINARY_INT8((i) >> 8),   PRINTF_BYTE_TO_BINARY_INT8(i)
#define PRINTF_BINARY_PATTERN_INT32 \
    PRINTF_BINARY_PATTERN_INT16             PRINTF_BINARY_PATTERN_INT16
#define PRINTF_BYTE_TO_BINARY_INT32(i) \
    PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i)
#define PRINTF_BINARY_PATTERN_INT64    \
    PRINTF_BINARY_PATTERN_INT32             PRINTF_BINARY_PATTERN_INT32
#define PRINTF_BYTE_TO_BINARY_INT64(i) \
    PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i)
/* --- end macros --- */

#include <stdio.h>
int main() {
    long long int flag = 1648646756487983144ll;
    printf("My Flag "
           PRINTF_BINARY_PATTERN_INT64 "\n",
           PRINTF_BYTE_TO_BINARY_INT64(flag));
    return 0;
}

Ce sorties:

My Flag 0001011011100001001010110111110101111000100100001111000000101000

pour la lisibilité, vous pouvez ajouter un séparateur pour par exemple:

My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
14
répondu ideasman42 2017-06-21 19:56:31

Imprimer le bit le moins significatif et déplacement sur la droite. Faire ceci jusqu'à ce que le nombre entier devienne zéro imprime la représentation binaire sans zéros de tête mais dans l'ordre inverse. En utilisant la récursion, l'ordre peut être corrigé assez facilement.

#include <stdio.h>

void print_binary(int number)
{
    if (number) {
        print_binary(number >> 1);
        putc((number & 1) ? '1' : '0', stdout);
    }
}

pour moi, c'est l'une des solutions les plus propres au problème. Si vous aimez le préfixe 0b et un nouveau caractère de ligne, je suggère d'envelopper la fonction.

Démo en ligne

13
répondu danijar 2015-04-28 13:18:47
const char* byte_to_binary( int x )
{
    static char b[sizeof(int)*8+1] = {0};
    int y;
    long long z;
    for (z=1LL<<sizeof(int)*8-1,y=0; z>0; z>>=1,y++)
    {
        b[y] = ( ((x & z) == z) ? '1' : '0');
    }

    b[y] = 0;

    return b;
}
11
répondu DanSkeel 2012-10-09 21:14:06

aucune des réponses précédemment affichées N'est exactement ce que je cherchais, donc j'en ai écrit une. Il est très simple d'utiliser %B avec le printf !

    /*
     * File:   main.c
     * Author: Techplex.Engineer
     *
     * Created on February 14, 2012, 9:16 PM
     */

    #include <stdio.h>
    #include <stdlib.h>
    #include <printf.h>
    #include <math.h>
    #include <string.h>


    static int printf_arginfo_M(const struct printf_info *info, size_t n, int *argtypes) {
        /* "%M" always takes one argument, a pointer to uint8_t[6]. */
        if (n > 0) {
            argtypes[0] = PA_POINTER;
        }
        return 1;
    } /* printf_arginfo_M */

    static int printf_output_M(FILE *stream, const struct printf_info *info, const void *const *args) {
        int value = 0;
        int len;

        value = *(int **) (args[0]);

        //Beginning of my code ------------------------------------------------------------
        char buffer [50] = ""; //Is this bad?
        char buffer2 [50] = ""; //Is this bad?
        int bits = info->width;
        if (bits <= 0)
            bits = 8; // Default to 8 bits

        int mask = pow(2, bits - 1);
        while (mask > 0) {
            sprintf(buffer, "%s", (((value & mask) > 0) ? "1" : "0"));
            strcat(buffer2, buffer);
            mask >>= 1;
        }
        strcat(buffer2, "\n");
        // End of my code --------------------------------------------------------------
        len = fprintf(stream, "%s", buffer2);
        return len;
    } /* printf_output_M */

    int main(int argc, char** argv) {

        register_printf_specifier('B', printf_output_M, printf_arginfo_M);

        printf("%4B\n", 65);

        return (EXIT_SUCCESS);
    }
8
répondu TechplexEngineer 2017-12-25 21:01:35

certaines durées d'exécution supportent" %b " bien que ce ne soit pas une norme.

Voir aussi ici pour une discussion intéressante:

http://bytes.com/forum/thread591027.html

HTH

7
répondu rlerallut 2008-09-22 02:56:00

ce code devrait répondre à vos besoins jusqu'à 64 bits. J'ai créé 2 fonctions pBin & pBinFill. Les deux font la même chose, mais pBinFill remplit les espaces principaux avec le fillChar. La fonction test génère des données de test, puis les imprime à l'aide de la fonction.



char* pBinFill(long int x,char *so, char fillChar); // version with fill
char* pBin(long int x, char *so);                   // version without fill
#define kDisplayWidth 64

char* pBin(long int x,char *so)
{
 char s[kDisplayWidth+1];
 int  i=kDisplayWidth;
 s[i--]=0x00;   // terminate string
 do
 { // fill in array from right to left
  s[i--]=(x & 1) ? '1':'0';  // determine bit
  x>>=1;  // shift right 1 bit
 } while( x &gt 0);
 i++;   // point to last valid character
 sprintf(so,"%s",s+i); // stick it in the temp string string
 return so;
}

char* pBinFill(long int x,char *so, char fillChar)
{ // fill in array from right to left
 char s[kDisplayWidth+1];
 int  i=kDisplayWidth;
 s[i--]=0x00;   // terminate string
 do
 { // fill in array from right to left
  s[i--]=(x & 1) ? '1':'0';
  x>>=1;  // shift right 1 bit
 } while( x > 0);
 while(i>=0) s[i--]=fillChar;    // fill with fillChar 
 sprintf(so,"%s",s);
 return so;
}

void test()
{
 char so[kDisplayWidth+1]; // working buffer for pBin
 long int val=1;
 do
 {
   printf("%ld =\t\t%#lx =\t\t0b%s\n",val,val,pBinFill(val,so,'0'));
   val*=11; // generate test data
 } while (val < 100000000);
}

Output:
00000001 =  0x000001 =  0b00000000000000000000000000000001
00000011 =  0x00000b =  0b00000000000000000000000000001011
00000121 =  0x000079 =  0b00000000000000000000000001111001
00001331 =  0x000533 =  0b00000000000000000000010100110011
00014641 =  0x003931 =  0b00000000000000000011100100110001
00161051 =  0x02751b =  0b00000000000000100111010100011011
01771561 =  0x1b0829 =  0b00000000000110110000100000101001
19487171 = 0x12959c3 =  0b00000001001010010101100111000011
6
répondu mrwes 2011-04-22 22:45:29

y a-t-il un convertisseur printf pour imprimer en format binaire?

la famille printf() ne peut imprimer qu'en base 8, 10 et 16 en utilisant directement les spécificateurs standards. Je suggère de créer une fonction qui convertit le nombre en une chaîne de caractères pour les besoins particuliers du code.


pour imprimer dans n'importe quelle base [2-36]

toutes les autres réponses jusqu'à présent, ont au moins une de ces limites.

  1. utilisez la mémoire statique pour le tampon de retour. Cela limite le nombre de fois où la fonction peut être utilisée comme argument à printf() .

  2. attribuer la mémoire nécessitant le code d'appel à des pointeurs libres.

  3. Exigent que le code appelant explicitement à fournir un tampon approprié.

  4. appelez printf() directement. Cela oblige une nouvelle fonction pour fprintf() , sprintf() , vsprintf() , etc.

  5. utilisez un nombre entier réduit.

le texte suivant a aucune des limitations ci-dessus . Il ne nécessite C99 ou plus et l'utilisation de "%s" . Il utilise un composé littéral pour fournir l'espace de mémoire tampon. Il n'a aucun problème avec les appels multiples dans un printf() .

#include <assert.h>
#include <limits.h>
#define TO_BASE_N (sizeof(unsigned)*CHAR_BIT + 1)

//                               v. compound literal .v
#define TO_BASE(x, b) my_to_base((char [TO_BASE_N]){""}, (x), (b))

// Tailor the details of the conversion function as needed
// This one does not display unneeded leading zeros
// Use return value, not `buf`
char *my_to_base(char *buf, unsigned i, int base) {
  assert(base >= 2 && base <= 36);
  char *s = &buf[TO_BASE_N - 1];
  *s = '"151900920"';
  do {
    s--;
    *s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i % base];
    i /= base;
  } while (i);

  // Could employ memmove here to move the used buffer to the beginning

  return s;
}

#include <stdio.h>
int main(void) {
  int ip1 = 0x01020304;
  int ip2 = 0x05060708;
  printf("%s %s\n", TO_BASE(ip1, 16), TO_BASE(ip2, 16));
  printf("%s %s\n", TO_BASE(ip1, 2), TO_BASE(ip2, 2));
  puts(TO_BASE(ip1, 8));
  return 0;
}

sortie

1020304 5060708
1000000100000001100000100 101000001100000011100001000
100401404
6
répondu chux 2018-05-12 21:07:55

peut-être un peu trop, mais si vous n'en avez besoin que pour déboguer pour comprendre ou retracer certaines opérations binaires que vous faites, vous pourriez jeter un oeil à wcalc (une simple calculatrice de console). Avec les options-b vous obtenez la sortie binaire.

p.ex.

$ wcalc -b "(256 | 3) & 0xff"
 = 0b11
5
répondu quinmars 2008-09-22 08:25:57

j'ai optimisé la meilleure solution pour la taille et C++ - ness, et suis arrivé à cette solution:

inline std::string format_binary(unsigned int x)
{
    static char b[33];
    b[32] = '"151900920"';

    for (int z = 0; z < 32; z++) {
        b[31-z] = ((x>>z) & 0x1) ? '1' : '0';
    }

    return b;
}
5
répondu paniq 2011-07-17 13:19:49

il n'y a pas de fonction de formatage dans la bibliothèque C standard pour la sortie binaire comme cela. Toutes les opérations de format que la famille printf supporte sont vers du texte lisible par l'homme.

5
répondu Florian Bösch 2017-12-25 21:06:39

la fonction récursive suivante pourrait être utile:

void bin(int n)
{
    /* Step 1 */
    if (n > 1)
        bin(n/2);
    /* Step 2 */
    printf("%d", n % 2);
}
5
répondu kapil 2017-12-25 21:16:57

j'ai aimé le code par paniq, la statique de la mémoire tampon est une bonne idée. Cependant, il échoue si vous voulez plusieurs formats binaires dans un seul printf () parce qu'il renvoie toujours le même pointeur et écrase le tableau.

voici un drop-in de style C qui fait tourner le pointeur sur un tampon divisé.

char *
format_binary(unsigned int x)
{
    #define MAXLEN 8 // width of output format
    #define MAXCNT 4 // count per printf statement
    static char fmtbuf[(MAXLEN+1)*MAXCNT];
    static int count = 0;
    char *b;
    count = count % MAXCNT + 1;
    b = &fmtbuf[(MAXLEN+1)*count];
    b[MAXLEN] = '"151900920"';
    for (int z = 0; z < MAXLEN; z++) { b[MAXLEN-1-z] = ((x>>z) & 0x1) ? '1' : '0'; }
    return b;
}
3
répondu eMPee584 2011-08-21 13:57:21

Pas de standard et portable.

certaines implémentations fournissent itoa() , mais ce ne sera pas dans la plupart des cas, et il a une interface quelque peu crummy. Mais le code est derrière le lien et devrait vous permettre d'implémenter votre propre formatteur assez facilement.

3
répondu wnoise 2014-02-26 02:08:00

imprimer des bits de tout type en utilisant moins de code et de ressources

Cette approche a comme attributs:

  • Fonctionne avec des variables et des littéraux.
  • n'itère pas tous les bits quand ce n'est pas nécessaire.
  • Call printf seulement lorsque remplir un octet (pas inutilement pour tous les bits).
  • fonctionne pour tout type.
  • fonctionne avec peu et grande endiannness (utilise GCC #définit pour la vérification).
  • utilise la typeof() qui n'est pas la norme C mais qui est largement définie.
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define for_endian(size) for (int i = 0; i < size; ++i)
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#define for_endian(size) for (int i = size - 1; i >= 0; --i)
#else
#error "Endianness not detected"
#endif

#define printb(value)                                   \
({                                                      \
        typeof(value) _v = value;                       \
        __printb((typeof(_v) *) &_v, sizeof(_v));       \
})

void __printb(void *value, size_t size)
{
        uint8_t byte;
        size_t blen = sizeof(byte) * 8;
        uint8_t bits[blen + 1];

        bits[blen] = '" 151900920"';
        for_endian(size) {
                byte = ((uint8_t *) value)[i];
                memset(bits, '0', blen);
                for (int j = 0; byte && j < blen; ++j) {
                        if (byte & 0x80)
                                bits[j] = '1';
                        byte <<= 1;
                }
                printf("%s ", bits);
        }
        printf("\n");
}

int main(void)
{
        uint8_t c1 = 0xff, c2 = 0x44;
        uint8_t c3 = c1 + c2;

        printb(c1);
        printb((char) 0xff);
        printb((short) 0xff);
        printb(0xff);
        printb(c2);
        printb(0x44);
        printb(0x4411ff01);
        printb((uint16_t) c3);
        printf("\n");

        return 0;
}

sortie

$ ./printb 
11111111 
11111111 
00000000 11111111 
00000000 00000000 00000000 11111111 
01000100 
00000000 00000000 00000000 01000100 
01000100 00010001 11111111 00000001 
00000000 01000011 

j'ai utilisé une autre approche ( bitprint.h ) pour remplir une table avec tous les octets (en tant que chaînes de bits) et les imprimer sur la base du byte input/index. Il vaut la peine de prendre un coup d'oeil.

3
répondu Geyslan G. Bem 2016-09-14 16:09:47

ma solution:

long unsigned int i;
for(i = 0u; i < sizeof(integer) * CHAR_BIT; i++) {
    if(integer & LONG_MIN)
        printf("1");
    else
        printf("0");
    integer <<= 1;
}
printf("\n");
3
répondu SarahGaidi 2016-12-22 20:00:06

basé sur la suggestion de @ideasman42 dans sa réponse, c'est une macro qui fournit int8 , 16 , 32 & 64 versions, en réutilisant la macro INT8 pour éviter la répétition.

/* --- PRINTF_BYTE_TO_BINARY macro's --- */
#define PRINTF_BINARY_SEPARATOR
#define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
#define PRINTF_BYTE_TO_BINARY_INT8(i)    \
    (((i) & 0x80ll) ? '1' : '0'), \
    (((i) & 0x40ll) ? '1' : '0'), \
    (((i) & 0x20ll) ? '1' : '0'), \
    (((i) & 0x10ll) ? '1' : '0'), \
    (((i) & 0x08ll) ? '1' : '0'), \
    (((i) & 0x04ll) ? '1' : '0'), \
    (((i) & 0x02ll) ? '1' : '0'), \
    (((i) & 0x01ll) ? '1' : '0')

#define PRINTF_BINARY_PATTERN_INT16 \
    PRINTF_BINARY_PATTERN_INT8               PRINTF_BINARY_SEPARATOR              PRINTF_BINARY_PATTERN_INT8
#define PRINTF_BYTE_TO_BINARY_INT16(i) \
    PRINTF_BYTE_TO_BINARY_INT8((i) >> 8),   PRINTF_BYTE_TO_BINARY_INT8(i)
#define PRINTF_BINARY_PATTERN_INT32 \
    PRINTF_BINARY_PATTERN_INT16              PRINTF_BINARY_SEPARATOR              PRINTF_BINARY_PATTERN_INT16
#define PRINTF_BYTE_TO_BINARY_INT32(i) \
    PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i)
#define PRINTF_BINARY_PATTERN_INT64    \
    PRINTF_BINARY_PATTERN_INT32              PRINTF_BINARY_SEPARATOR              PRINTF_BINARY_PATTERN_INT32
#define PRINTF_BYTE_TO_BINARY_INT64(i) \
    PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i)
/* --- end macros --- */

#include <stdio.h>
int main() {
    long long int flag = 1648646756487983144ll;
    printf("My Flag "
           PRINTF_BINARY_PATTERN_INT64 "\n",
           PRINTF_BYTE_TO_BINARY_INT64(flag));
    return 0;
}

Ce sorties:

My Flag 0001011011100001001010110111110101111000100100001111000000101000

pour la lisibilité, vous pouvez changer: #define PRINTF_BINARY_SEPARATOR en #define PRINTF_BINARY_SEPARATOR "," ou #define PRINTF_BINARY_SEPARATOR " "

Ce sera de sortie:

My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000

ou

My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000
3
répondu Et7f3XIV 2017-07-21 12:47:31
void
print_binary(unsigned int n)
{
    unsigned int mask = 0;
    /* this grotesque hack creates a bit pattern 1000... */
    /* regardless of the size of an unsigned int */
    mask = ~mask ^ (~mask >> 1);

    for(; mask != 0; mask >>= 1) {
        putchar((n & mask) ? '1' : '0');
    }

}
3
répondu малин чекуров 2018-05-12 20:51:34
void print_ulong_bin(const unsigned long * const var, int bits) {
        int i;

        #if defined(__LP64__) || defined(_LP64)
                if( (bits > 64) || (bits <= 0) )
        #else
                if( (bits > 32) || (bits <= 0) )
        #endif
                return;

        for(i = 0; i < bits; i++) { 
                printf("%lu", (*var >> (bits - 1 - i)) & 0x01);
        }
}

devrait fonctionner - non testé.

2
répondu olli 2010-09-30 19:05:07
/* Convert an int to it's binary representation */

char *int2bin(int num, int pad)
{
 char *str = malloc(sizeof(char) * (pad+1));
  if (str) {
   str[pad]='"151900920"';
   while (--pad>=0) {
    str[pad] = num & 1 ? '1' : '0';
    num >>= 1;
   }
  } else {
   return "";
  }
 return str;
}

/* example usage */

printf("The number 5 in binary is %s", int2bin(5, 4));
/* "The number 5 in binary is 0101" */
2
répondu Ben Cordero 2011-07-01 15:26:25

suivant affichera la mise en page de la mémoire:

#include <limits>
#include <iostream>
#include <string>

using namespace std;

template<class T> string binary_text(T dec, string byte_separator = " ") {
    char* pch = (char*)&dec;
    string res;
    for (int i = 0; i < sizeof(T); i++) {
        for (int j = 1; j < 8; j++) {
            res.append(pch[i] & 1 ? "1" : "0");
            pch[i] /= 2;
        }
        res.append(byte_separator);
    }
    return res;
}

int main() {
    cout << binary_text(5) << endl;
    cout << binary_text(.1) << endl;

    return 0;
}
2
répondu Yola 2012-01-15 10:57:58

Voici une petite variation de la solution de paniq qui utilise des gabarits pour permettre l'impression d'entiers 32 et 64 bits:

template<class T>
inline std::string format_binary(T x)
{
    char b[sizeof(T)*8+1] = {0};

    for (size_t z = 0; z < sizeof(T)*8; z++)
        b[sizeof(T)*8-1-z] = ((x>>z) & 0x1) ? '1' : '0';

    return std::string(b);
}

et peut être utilisé comme:

unsigned int value32 = 0x1e127ad;
printf( "  0x%x: %s\n", value32, format_binary(value32).c_str() );

unsigned long long value64 = 0x2e0b04ce0;
printf( "0x%llx: %s\n", value64, format_binary(value64).c_str() );

voici le résultat:

  0x1e127ad: 00000001111000010010011110101101
0x2e0b04ce0: 0000000000000000000000000000001011100000101100000100110011100000
2
répondu Leo 2013-12-04 05:22:50

je veux juste poster ma solution. Il est utilisé pour obtenir des zéros et ceux d'un octet, mais appeler cette fonction peu de fois peut être utilisé pour les blocs de données plus grands. Je l'utilise pour des structures de 128 bits ou plus. Vous pouvez également le modifier pour utiliser size_t comme paramètre d'entrée et pointeur vers les données que vous voulez imprimer, de sorte qu'il peut être indépendant de la taille. Mais cela fonctionne pour moi de quitter bien comme il est.

void print_binary(unsigned char c)
{
 unsigned char i1 = (1 << (sizeof(c)*8-1));
 for(; i1; i1 >>= 1)
      printf("%d",(c&i1)!=0);
}

void get_binary(unsigned char c, unsigned char bin[])
{
 unsigned char i1 = (1 << (sizeof(c)*8-1)), i2=0;
 for(; i1; i1>>=1, i2++)
      bin[i2] = ((c&i1)!=0);
}
2
répondu Marko 2014-03-19 15:52:27

Voici comment je l'ai fait pour un int non signé

void printb(unsigned int v) {
    unsigned int i, s = 1<<((sizeof(v)<<3)-1); // s = only most significant bit at 1
    for (i = s; i; i>>=1) printf("%d", v & i || 0 );
}
2
répondu andre.barata 2014-08-26 10:56:38

une petite fonction utilitaire en C pour faire ceci tout en résolvant un problème de manipulation de bits. Ceci va au-delà de la chaîne de vérification de chaque bit défini à l'aide d'un masque (1<

void
printStringAsBinary(char * input)
{
    char * temp = input;
    int i = 7, j =0;;
    int inputLen = strlen(input);

    /* Go over the string, check first bit..bit by bit and print 1 or 0
     **/

    for (j = 0; j < inputLen; j++) {
        printf("\n");
        while (i>=0) {
            if (*temp & (1 << i)) {
               printf("1");
            } else {
                printf("0");
            }
            i--;
        }
        temp = temp+1;
        i = 7;
        printf("\n");
    }
}
2
répondu Gaurav Sinha 2014-10-02 04:37:06