Is er een printf-converter om in binair formaat af te drukken?

Ik kan afdrukken met printfals hexadecimaal of octaal getal. Is er een formaattag om als binaire of willekeurige basis af te drukken?

Ik gebruik gcc.

printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
print("%b\n", 10); // prints "%b\n"

Antwoord 1, autoriteit 100%

Hacky maar werkt voor mij:

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

Voor typen met meerdere bytes

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

Je hebt helaas alle extra aanhalingstekens nodig. Deze aanpak heeft de efficiëntierisico’s van macro’s (geef geen functie als argument door aan BYTE_TO_BINARY), maar vermijdt de geheugenproblemen en meerdere aanroepen van strcat in sommige van de andere voorstellen hier.


Antwoord 2, autoriteit 72%

Binair afdrukken voor elk gegevenstype

// 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("");
}

Testen:

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

Antwoord 3, autoriteit 53%

Hier is een snelle hack om technieken te demonstreren om te doen wat je wilt.

#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] = '\0';
    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;
}

Antwoord 4, autoriteit 29%

Normaal gesproken is er geen binaire conversiespecificatie in glibc.

Het is mogelijk om aangepaste conversietypes toe te voegen aan de printf()-familie van functies in glibc. Zie register_printf_functionvoor details. U kunt een aangepaste %b-conversie toevoegen voor eigen gebruik, als dit de applicatiecode vereenvoudigt om deze beschikbaar te hebben.

Hier is een voorbeeldvan het implementeren van een aangepaste printf-indeling in glibc.


Antwoord 5, autoriteit 18%

Je zou een kleine tabel kunnen gebruiken om snelheid1te verbeteren. Soortgelijke technieken zijn nuttig in de embedded wereld, bijvoorbeeld om een byte om te keren:

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

1Ik verwijs vooral naar embedded applicaties waar optimizers niet zo agressief zijn en het snelheidsverschil zichtbaar is.


Antwoord 6, autoriteit 12%

Druk het minst significante bit af en schuif het naar rechts. Als u dit doet totdat het gehele getal nul wordt, wordt de binaire weergave afgedrukt zonder voorloopnullen, maar in omgekeerde volgorde. Met behulp van recursie kan de volgorde vrij eenvoudig worden gecorrigeerd.

#include <stdio.h>
void print_binary(unsigned int number)
{
    if (number >> 1) {
        print_binary(number >> 1);
    }
    putc((number & 1) ? '1' : '0', stdout);
}

Voor mij is dit een van de schoonste oplossingen voor het probleem. Als je het voorvoegsel 0ben een teken van een nieuwe regel aan het einde leuk vindt, raad ik aan om de functie in te pakken.

Online demo


Antwoord 7, autoriteit 8%

Op basis van het antwoord van @William Whyte is dit een macro die INT8,16,32& 64versies, waarbij de macro INT8opnieuw wordt gebruikt om herhaling te voorkomen.

/* --- 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;
}

Dit geeft het volgende weer:

My Flag 0001011011100001001010110111110101111000100100001111000000101000

Voor de leesbaarheid wilt u misschien een scheidingsteken toevoegen voor bijvoorbeeld:

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

Antwoord 8, autoriteit 6%

Hier is een versie van de functie die geen last heeft van herintredingsproblemen of beperkingen op de grootte/type van het 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;
}

Merk op dat deze code net zo goed zou werken voor elk grondtal tussen 2 en 10 als je de 2’s vervangt door het gewenste grondtal. Gebruik is:

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

Waar xeen integrale uitdrukking is.


Antwoord 9, autoriteit 5%

Snelle en gemakkelijke oplossing:

void printbits(my_integer_type x)
{
    for(int i=sizeof(x)<<3; i; i--)
        putchar('0'+((x>>(i-1))&1));
}

Werkt voor elk type formaat en voor ondertekende en niet-ondertekende ints. De ‘&1’ is nodig om ondertekende ints af te handelen, aangezien de ploeg extensie kan ondertekenen.

Er zijn zoveel manieren om dit te doen. Hier is een supereenvoudige voor het afdrukken van 32 bits of n bits van een ondertekend of niet-ondertekend 32-bits type (geen negatief plaatsen indien ondertekend, alleen de daadwerkelijke bits afdrukken) en geen regelterugloop. Merk op dat i wordt verlaagd vóór de bitverschuiving:

#define printbits_n(x,n) for (int i=n;i;i--,putchar('0'|(x>>i)&1))
#define printbits_32(x) printbits_n(x,32)

Hoe zit het met het retourneren van een string met de bits om later op te slaan of af te drukken? Je kunt ofwel het geheugen toewijzen en het teruggeven en de gebruiker moet het vrijgeven, of je retourneert een statische string, maar hij wordt belazerd als hij opnieuw wordt aangeroepen, of door een andere thread. Beide getoonde methoden:

char *int_to_bitstring_alloc(int x, int count)
{
    count = count<1 ? sizeof(x)*8 : count;
    char *pstr = malloc(count+1);
    for(int i = 0; i<count; i++)
        pstr[i] = '0' | ((x>>(count-1-i))&1);
    pstr[count]=0;
    return pstr;
}
#define BITSIZEOF(x)    (sizeof(x)*8)
char *int_to_bitstring_static(int x, int count)
{
    static char bitbuf[BITSIZEOF(x)+1];
    count = (count<1 || count>BITSIZEOF(x)) ? BITSIZEOF(x) : count;
    for(int i = 0; i<count; i++)
        bitbuf[i] = '0' | ((x>>(count-1-i))&1);
    bitbuf[count]=0;
    return bitbuf;
}

Bel met:

// memory allocated string returned which needs to be freed
char *pstr = int_to_bitstring_alloc(0x97e50ae6, 17);
printf("bits = 0b%s\n", pstr);
free(pstr);
// no free needed but you need to copy the string to save it somewhere else
char *pstr2 = int_to_bitstring_static(0x97e50ae6, 17);
printf("bits = 0b%s\n", pstr2);

Antwoord 10, autoriteit 4%

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

Antwoord 11, autoriteit 4%

Geen van de eerder geposte antwoorden is precies wat ik zocht, dus schreef ik er een. Het is supereenvoudig om %Bte gebruiken met de 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;
}
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;
}
int main(int argc, char** argv)
{
    register_printf_specifier('B', printf_output_M, printf_arginfo_M);
    printf("%4B\n", 65);
    return EXIT_SUCCESS;
}

Antwoord 12, autoriteit 4%

Is er een printf-converter om in binair formaat af te drukken?

De printf()-familie kan alleen gehele getallen met grondtal 8, 10 en 16 rechtstreeks afdrukken met behulp van de standaardspecificaties. Ik stel voor om een functie te maken die het getal converteert naar een tekenreeks volgens de specifieke behoeften van de code.


Afdrukken in een willekeurige basis [2-36]

Alle andere antwoorden tot nu toe hebben ten minste één van deze beperkingen.

  1. Gebruik statisch geheugen voor de retourbuffer. Dit beperkt het aantal keren dat de functie als argument kan worden gebruikt voor printf().

  2. Wijs geheugen toe waarvoor de oproepcode nodig is om aanwijzers vrij te maken.

  3. Vereisen dat de aanroepcode expliciet een geschikte buffer biedt.

  4. Bel printf()rechtstreeks. Dit verplicht een nieuwe functie voor fprintf(), sprintf(), vsprintf(), etc.

  5. Gebruik een kleiner geheel getal.

Het volgende heeft geen van de bovenstaande beperkingen. Het vereist wel C99 of hoger en het gebruik van "%s". Het gebruikt een samengestelde letterlijkeom de buffer te leveren ruimte. Het heeft geen problemen met meerdere aanroepen in een 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[TO_BASE_N], unsigned i, int base) {
  assert(base >= 2 && base <= 36);
  char *s = &buf[TO_BASE_N - 1];
  *s = '\0';
  do {
    s--;
    *s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i % base];
    i /= base;
  } while (i);
  // Could employ memmove here to move the used buffer to the beginning
  // size_t len = &buf[TO_BASE_N] - s;
  // memmove(buf, s, len);
  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));
  puts(TO_BASE(ip1, 36));
  return 0;
}

Uitvoer

1020304 5060708
1000000100000001100000100 101000001100000011100001000
100401404
A2F44

Antwoord 13, autoriteit 3%

Deze code moet voldoen aan uw behoeften tot 64 bits.
Ik heb twee functies gemaakt: pBinen pBinFill. Beide doen hetzelfde, maar pBinFillvult de voorloopspaties in met het opvulteken van het laatste argument.
De testfunctie genereert enkele testgegevens en drukt deze vervolgens af met de functie pBinFill.

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

Uitvoer:

00000001 =  0x000001 =  0b00000000000000000000000000000001
00000011 =  0x00000b =  0b00000000000000000000000000001011
00000121 =  0x000079 =  0b00000000000000000000000001111001
00001331 =  0x000533 =  0b00000000000000000000010100110011
00014641 =  0x003931 =  0b00000000000000000011100100110001
00161051 =  0x02751b =  0b00000000000000100111010100011011
01771561 =  0x1b0829 =  0b00000000000110110000100000101001
19487171 = 0x12959c3 =  0b00000001001010010101100111000011

Antwoord 14, autoriteit 2%

Sommige runtimes ondersteunen “%b”, hoewel dat geen standaard is.

Zie ook hier voor een interessante discussie:

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

HTH


Antwoord 15, autoriteit 2%

Misschien een beetje OT, maar als je dit alleen nodig hebt voor het debuggen om een aantal binaire bewerkingen die je doet te begrijpen of te achterhalen, zou je eens kunnen kijken op wcalc (een eenvoudige consolecalculator). Met de -b opties krijg je binaire output.

bijv.

$ wcalc -b "(256 | 3) & 0xff"
 = 0b11

Antwoord 16, autoriteit 2%

Er is geen opmaakfunctie in de C-standaardbibliotheek om zo binair uit te voeren. Alle formaatbewerkingen die de printf-familie ondersteunt, zijn gericht op door mensen leesbare tekst.


Antwoord 17, autoriteit 2%

De volgende recursieve functie kan nuttig zijn:

void bin(int n)
{
    /* Step 1 */
    if (n > 1)
        bin(n/2);
    /* Step 2 */
    printf("%d", n % 2);
}

Antwoord 18, autoriteit 2%

Ik heb de topoplossing geoptimaliseerd voor grootte en C++-heid en kwam tot deze oplossing:

inline std::string format_binary(unsigned int x)
{
    static char b[33];
    b[32] = '\0';
    for (int z = 0; z < 32; z++) {
        b[31-z] = ((x>>z) & 0x1) ? '1' : '0';
    }
    return b;
}

Antwoord 19, autoriteit 2%

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

Antwoord 20

Gebruik:

char buffer [33];
itoa(value, buffer, 2);
printf("\nbinary: %s\n", buffer);

Voor meer referentie, zie Hoe een binair getal af te drukken via printf.


Antwoord 21

Print bits van elk type met minder code en middelen

Deze aanpak heeft als kenmerken:

  • Werkt met variabelen en letterlijke waarden.
  • Itereert niet alle bits wanneer dit niet nodig is.
  • Bel printf alleen aan als een byte compleet is (niet onnodig voor alle bits).
  • Werkt voor elk type.
  • Werkt met little en big endianness (gebruikt GCC #defines voor controle).
  • Kan werken met hardware waarvan de char geen byte is (acht bits). (Tks @supercat)
  • Gebruikt typeof() dat niet de C-standaard is, maar grotendeels gedefinieerd is.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <limits.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));       \
})
#define MSB_MASK 1 << (CHAR_BIT - 1)
void __printb(void *value, size_t size)
{
        unsigned char uc;
        unsigned char bits[CHAR_BIT + 1];
        bits[CHAR_BIT] = '\0';
        for_endian(size) {
                uc = ((unsigned char *) value)[i];
                memset(bits, '0', CHAR_BIT);
                for (int j = 0; uc && j < CHAR_BIT; ++j) {
                        if (uc & MSB_MASK)
                                bits[j] = '1';
                        uc <<= 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);
        printb('A');
        printf("\n");
        return 0;
}

Uitvoer

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

Ik heb een anderebenadering gebruikt (bitprint.h) om een tabel te vullen met alle bytes (als bitstrings) en ze af te drukken op basis van de invoer/indexbyte. Het is de moeite waard om een kijkje te nemen.


Antwoord 22

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

zou moeten werken – niet getest.


Antwoord 23

Ik vond de code van paniq leuk, de statische buffer is een goed idee. Het mislukt echter als u meerdere binaire formaten in één printf() wilt, omdat het altijd dezelfde aanwijzer retourneert en de array overschrijft.

Hier is een drop-in in C-stijl die de aanwijzer op een gesplitste buffer roteert.

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] = '\0';
    for (int z = 0; z < MAXLEN; z++) { b[MAXLEN-1-z] = ((x>>z) & 0x1) ? '1' : '0'; }
    return b;
}

Antwoord 24

Geen standaard en draagbare manier.

Sommige implementaties bieden itoa(), maar het is niet in de meeste, en het heeft een ietwat slordige interface. Maar de code zit achter de link en zou je vrij gemakkelijk je eigen formatter moeten laten implementeren.


Antwoord 25

Dit is hoe ik het deed voor een niet-ondertekende int

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

Antwoord 26

Een algemene instructieconversie van elk integraal typenaar de binaire tekenreeksrepresentatie met behulp van standaardbibliotheek:

#include <bitset>
MyIntegralType  num = 10;
print("%s\n",
    std::bitset<sizeof(num) * 8>(num).to_string().insert(0, "0b").c_str()
); // prints "0b1010\n"

Of gewoon:std::cout << std::bitset<sizeof(num) * 8>(num);


Antwoord 27

Mijn oplossing:

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

Antwoord 28

Gebaseerd op de suggestie van @ideasman42 in zijn antwoord, is dit een macro die INT8,16,32& 64versies, waarbij de macro INT8opnieuw wordt gebruikt om herhaling te voorkomen.

/* --- 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;
}

Dit geeft het volgende weer:

My Flag 0001011011100001001010110111110101111000100100001111000000101000

Voor de leesbaarheid kunt u :#define PRINTF_BINARY_SEPARATORwijzigen in #define PRINTF_BINARY_SEPARATOR ","of #define PRINTF_BINARY_SEPARATOR " "

Dit levert het volgende op:

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

of

My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000

Antwoord 29

/* 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]='\0';
   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" */

Antwoord 30

Volgende zal u de geheugenlay-out tonen:

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

Other episodes