Kan ik een binaire letterlijke in C of C++ gebruiken?

Ik moet met een binair getal werken.

Ik heb geprobeerd schrijven:

const x = 00010000;

Maar het werkte niet.

Ik weet dat ik een hexadecimaal nummer kan gebruiken dat dezelfde waarde heeft als 00010000, maar ik wil weten of er een type in C++ is voor binaire getallen en als dat niet is Er is een andere oplossing voor mijn probleem?


Antwoord 1, Autoriteit 100%

U kunt Gebruik BOOST_BINARYtijdens het wachten op C++ 0x. 🙂 BOOST_BINARYMogelijk heeft een voordeel ten opzichte van sjabloonimplementatie voor zover het ook in C-programma’s kan worden gebruikt (het is 100% preprocessor-driven.)

Om het omgekeerde te doen (dwz afdruk een getal in binaire formulier), kunt u de niet-draagbare itoaFUNCTION , of Implementeer uw eigen .

Helaas kunt u geen basis 2 formatteren met stl-streams (sinds setbaseZAL ALLEEN HONOREN BASES 8, 10 EN 16), MAAR U CAN Gebruik een std::stringVersie van itoa, of (hoe meer beknopt, maar marginaal minder efficiënt) std::bitset.

#include <boost/utility/binary.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <bitset>
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
  unsigned short b = BOOST_BINARY( 10010 );
  char buf[sizeof(b)*8+1];
  printf("hex: %04x, dec: %u, oct: %06o, bin: %16s\n", b, b, b, itoa(b, buf, 2));
  cout << setfill('0') <<
    "hex: " << hex << setw(4) << b << ", " <<
    "dec: " << dec << b << ", " <<
    "oct: " << oct << setw(6) << b << ", " <<
    "bin: " << bitset< 16 >(b) << endl;
  return 0;
}

produceert:

hex: 0012, dec: 18, oct: 000022, bin:            10010
hex: 0012, dec: 18, oct: 000022, bin: 0000000000010010

Lees ook Herb Sutter’s The String Formatters of Manor Farmvoor een interessante discussie.


Antwoord 2, autoriteit 91%

Als u GCC gebruikt, kunt u een GCC-extensiegebruiken (die is opgenomen in de C++14-standaard ) hiervoor:

int x = 0b00010000;

Antwoord 3, autoriteit 95%

U kunt binaire letterlijke waarden gebruiken. Ze zijn gestandaardiseerd in C++14. Bijvoorbeeld,

int x = 0b11000;

Ondersteuning in GCC

Ondersteuning in GCC begon in GCC 4.3 (zie https://gcc.gnu.org /gcc-4.3/changes.html) als uitbreidingen op de C-taalfamilie (zie https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions), maar sinds GCC 4.9 wordt het nu herkend als een C++ 14-functie of een extensie (zie Verschil tussen GCC binaire literalen en C++14-en?)

Ondersteuning in Visual Studio

Ondersteuning in Visual Studio is gestart in Visual Studio 2015 Preview (zie https:// www.visualstudio.com/news/vs2015-preview-vs#C++).


Antwoord 4, autoriteit 91%

template<unsigned long N>
struct bin {
    enum { value = (N%10)+2*bin<N/10>::value };
} ;
template<>
struct bin<0> {
    enum { value = 0 };
} ;
// ...
    std::cout << bin<1000>::value << '\n';

Het meest linkse cijfer van de letterlijke moet nog steeds 1 zijn, maar niettemin.


Antwoord 5, autoriteit 44%

Een paar compilers (meestal die voor microcontrollers) hebben een speciale functie geïmplementeerd bij het herkennen van letterlijke binaire getallen door prefix “0b…”voorafgaand aan het nummer, hoewel de meeste compilers (C/C++-standaarden) zo’n functie niet hebben en als dat het geval is, is hier mijn alternatieve oplossing:

#define B_0000    0
#define B_0001    1
#define B_0010    2
#define B_0011    3
#define B_0100    4
#define B_0101    5
#define B_0110    6
#define B_0111    7
#define B_1000    8
#define B_1001    9
#define B_1010    a
#define B_1011    b
#define B_1100    c
#define B_1101    d
#define B_1110    e
#define B_1111    f
#define _B2H(bits)    B_##bits
#define B2H(bits)    _B2H(bits)
#define _HEX(n)        0x##n
#define HEX(n)        _HEX(n)
#define _CCAT(a,b)    a##b
#define CCAT(a,b)   _CCAT(a,b)
#define BYTE(a,b)        HEX( CCAT(B2H(a),B2H(b)) )
#define WORD(a,b,c,d)    HEX( CCAT(CCAT(B2H(a),B2H(b)),CCAT(B2H(c),B2H(d))) )
#define DWORD(a,b,c,d,e,f,g,h)    HEX( CCAT(CCAT(CCAT(B2H(a),B2H(b)),CCAT(B2H(c),B2H(d))),CCAT(CCAT(B2H(e),B2H(f)),CCAT(B2H(g),B2H(h)))) )
// Using example
char b = BYTE(0100,0001); // Equivalent to b = 65; or b = 'A'; or b = 0x41;
unsigned int w = WORD(1101,1111,0100,0011); // Equivalent to w = 57155; or w = 0xdf43;
unsigned long int dw = DWORD(1101,1111,0100,0011,1111,1101,0010,1000); //Equivalent to dw = 3745774888; or dw = 0xdf43fd28;

Nadelen(het zijn niet zo’n grote):

  • De binaire getallen moeten 4 bij 4 worden gegroepeerd;
  • De binaire letterlijke waarden mogen alleen gehele getallen zonder teken zijn;

Voordelen:

  • Totaal preprocessorgestuurd, niet spending processor timein zinloze bewerkingen (like "?.. :..", "<<", "+") naar het uitvoerbare programma (het kan honderden keren worden uitgevoerd in de uiteindelijke toepassing);
  • Het werkt "mainly in C"-compilers en ook in C++ (template+enum solution works only in C++ compilers);
  • Het heeft alleen de beperking van “langheid” voor het uitdrukken van “letterlijke constante” waarden. Er zou een vroege beperking van de longness zijn geweest (meestal 8 bits: 0-255) als men constante waarden had uitgesproken door het parseren van de oplossing van "enum solution" (usually 255 = reach enum definition limit), anders ” Letterlijke constante “beperkingen, in de compiler maakt meer cijfers toe;
  • Enkele andere oplossingen Vraag overdreven aantal constante definities (te veel definieert naar mijn mening), inclusief lang of several header files(in de meeste gevallen niet gemakkelijk leesbaar en begrijpelijk, en laat het project onnodig verward worden en uitgebreid, zoals die met behulp van "BOOST_BINARY()");
  • Eenvoud van de oplossing: gemakkelijk leesbaar, begrijpelijk en verstelbaar voor andere gevallen (kan ook worden uitgebreid voor groep 8 door 8);

Antwoord 6, Autoriteit 28%

Deze draad kan helpen.

/* Helper macros */
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x&0x0000000FLU)?1:0) \
+((x&0x000000F0LU)?2:0) \
+((x&0x00000F00LU)?4:0) \
+((x&0x0000F000LU)?8:0) \
+((x&0x000F0000LU)?16:0) \
+((x&0x00F00000LU)?32:0) \
+((x&0x0F000000LU)?64:0) \
+((x&0xF0000000LU)?128:0)
/* User macros */
#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \
+ B8(dlsb))
#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) \
+ ((unsigned long)B8(db2)<<16) \
+ ((unsigned long)B8(db3)<<8) \
+ B8(dlsb))
#include <stdio.h>
int main(void)
{
    // 261, evaluated at compile-time
    unsigned const number = B16(00000001,00000101);
    printf("%d \n", number);
    return 0;
}

het werkt! (Alle credits gaan naar Tom Torfs.)


Antwoord 7, Autoriteit 24%

De C++ Over-Engineering Mindset is al goed goed voor in de andere antwoorden hier. Hier is mijn poging om het te doen met een C, Houder-IT-Simple-FFS Mindset:

unsigned char x = 0xF; // binary: 00001111

Antwoord 8, Autoriteit 24%

Zoals reeds beantwoord, hebben de C-normen geen manier om binaire getallen direct te schrijven. Er zijn echter compiler-extensies en blijkbaar omvat C++ 14 de 0bvoorvoegsel voor binair. (Merk op dat dit antwoord oorspronkelijk in 2010 werd gepost.)

Eén populaire oplossing is om een header-bestand met helper macro’s . Eén eenvoudige optie is ook om een ​​bestand te genereren dat macrodefinities bevat voor alle 8-bits patronen, b.v.:

#define B00000000 0
#define B00000001 1
#define B00000010 2
…

Dit resulteert in slechts 256 #defineS, en als grotere dan 8-bits binaire constanten nodig zijn, kunnen deze definities worden gecombineerd met verschuivingen en ors, mogelijk met helpermacro’s (bijv. BIN16(B00000001,B00001010)). (Met individuele macro’s voor elke 16-bits, laat staan ​​32-bits, waarde is niet aannemelijk.)

Natuurlijk is het nadeel dat deze syntaxis alle leidende nullen nodig is, maar dit kan het ook duidelijker maken voor gebruik zoals het instellen van bitvlaggen en inhoud van hardwaregegenisters. Voor een functie-achtige macro resulteert in een syntaxis zonder deze eigenschap, zie bithacks.hhierboven gekoppeld.


Antwoord 9, Autoriteit 17%

C heeft geen nativenotatie voor zuivere binaire getallen. Je beste gok is hier ofwel octaal(bijv. 07777) of hexadecimaal(bijv. 0xfff).


Antwoord 10, autoriteit 15%

U kunt de functie in deze vraaggebruiken om tot 22 bits in C++ te krijgen . Hier is de code van de link, passend bewerkt:

template< unsigned long long N >
struct binary
{
  enum { value = (N % 8) + 2 * binary< N / 8 > :: value } ;
};
template<>
struct binary< 0 >
{
  enum { value = 0 } ;
};

Je kunt dus iets doen als binary<0101011011>::value.


Antwoord 11, autoriteit 10%

De kleinste eenheid waarmee u kunt werken, is een byte (van het type char). U kunt echter met bits werken door bitsgewijze operatoren te gebruiken.

Voor letterlijke gehele getallen kunt u alleen werken met decimale (grondtal 10), octale (grondtal 8) of hexadecimale (grondtal 16) getallen. Er zijn geen binaire (grondtal 2) letterlijke waarden in C noch C++.

Octale getallen worden voorafgegaan door 0en hexadecimale getallen worden voorafgegaan door 0x. Decimale getallen hebben geen voorvoegsel.

In C++0x kun je trouwens doen wat je wilt via door de gebruiker gedefinieerde letterlijke waarden.


Antwoord 12, autoriteit 7%

U kunt inline montage ook als volgt gebruiken:

int i;
__asm {
    mov eax, 00000000000000000000000000000000b
    mov i,   eax
}
std::cout << i;

Ok, het is misschien wat overdreven, maar het werkt.


Antwoord 13, autoriteit 6%

Gebaseerd op enkele andere antwoorden, maar deze zal programma’s met illegale binaire letterlijke waarden afwijzen. Voorloopnullen zijn optioneel.

template<bool> struct BinaryLiteralDigit;
template<> struct BinaryLiteralDigit<true> {
    static bool const value = true;
};
template<unsigned long long int OCT, unsigned long long int HEX>
struct BinaryLiteral {
    enum {
        value = (BinaryLiteralDigit<(OCT%8 < 2)>::value && BinaryLiteralDigit<(HEX >= 0)>::value
            ? (OCT%8) + (BinaryLiteral<OCT/8, 0>::value << 1)
            : -1)
    };
};
template<>
struct BinaryLiteral<0, 0> {
    enum {
        value = 0
    };
};
#define BINARY_LITERAL(n) BinaryLiteral<0##n##LU, 0x##n##LU>::value

Voorbeeld:

#define B BINARY_LITERAL
#define COMPILE_ERRORS 0
int main (int argc, char ** argv) {
    int _0s[] = { 0, B(0), B(00), B(000) };
    int _1s[] = { 1, B(1), B(01), B(001) };
    int _2s[] = { 2, B(10), B(010), B(0010) };
    int _3s[] = { 3, B(11), B(011), B(0011) };
    int _4s[] = { 4, B(100), B(0100), B(00100) };
    int neg8s[] = { -8, -B(1000) };
#if COMPILE_ERRORS
    int errors[] = { B(-1), B(2), B(9), B(1234567) };
#endif
    return 0;
}

Antwoord 14, autoriteit 4%

Het “type” van een binair getal is hetzelfde als elk decimaal, hexadecimaal of octaal getal: int(of zelfs char, kort, lang lang).

Wanneer u een constante toewijst, kunt u deze niet toewijzen met 11011011 (vreemd genoeg en helaas), maar u kunt hex gebruiken. Hex is een beetje makkelijker om mentaal te vertalen. Verdeel in nibbles (4 bits) en vertaal naar een karakter in [0-9a-f].


Antwoord 15, Autoriteit 3%

U kunt een BITSET

gebruiken

bitset<8> b(string("00010000"));
int i = (int)(bs.to_ulong());
cout<<i;

Antwoord 16, Autoriteit 3%

Ik heb het goede antwoord uitgebreid gegeven door @ Renato-kroonluchter door te zorgen voor de ondersteuning van:

  • _NIBBLE_(…)– 4 BITS, 1 NABLIBLY ALS ARGUMENT
  • _BYTE_(…)– 8 bits, 2 hapjes als argumenten
  • _SLAB_(…)– 12 BITS, 3 Nibbles als argumenten
  • _WORD_(…)– 16 BITS, 4 hapjes als argumenten
  • _QUINTIBBLE_(…)– 20 BITS, 5 Nibbles als argumenten
  • _DSLAB_(…)– 24 BITS, 6 Nibbles als argumenten
  • _SEPTIBBLE_(…)– 28 BITS, 7 Nibbles als argumenten
  • _DWORD_(…)– 32 BITS, 8 hapjes als argumenten

Ik ben eigenlijk niet zo zeker van de termen “Quintible” en “Septiver”. Als iemand een alternatief kent, laat het me dan weten.

Hier is de macro herschreven:

#define __CAT__(A, B) A##B
#define _CAT_(A, B) __CAT__(A, B)
#define __HEX_0000 0
#define __HEX_0001 1
#define __HEX_0010 2
#define __HEX_0011 3
#define __HEX_0100 4
#define __HEX_0101 5
#define __HEX_0110 6
#define __HEX_0111 7
#define __HEX_1000 8
#define __HEX_1001 9
#define __HEX_1010 a
#define __HEX_1011 b
#define __HEX_1100 c
#define __HEX_1101 d
#define __HEX_1110 e
#define __HEX_1111 f
#define _NIBBLE_(N1) _CAT_(0x, _CAT_(__HEX_, N1))
#define _BYTE_(N1, N2) _CAT_(_NIBBLE_(N1), _CAT_(__HEX_, N2))
#define _SLAB_(N1, N2, N3) _CAT_(_BYTE_(N1, N2), _CAT_(__HEX_, N3))
#define _WORD_(N1, N2, N3, N4) _CAT_(_SLAB_(N1, N2, N3), _CAT_(__HEX_, N4))
#define _QUINTIBBLE_(N1, N2, N3, N4, N5) _CAT_(_WORD_(N1, N2, N3, N4), _CAT_(__HEX_, N5))
#define _DSLAB_(N1, N2, N3, N4, N5, N6) _CAT_(_QUINTIBBLE_(N1, N2, N3, N4, N5), _CAT_(__HEX_, N6))
#define _SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7) _CAT_(_DSLAB_(N1, N2, N3, N4, N5, N6), _CAT_(__HEX_, N7))
#define _DWORD_(N1, N2, N3, N4, N5, N6, N7, N8) _CAT_(_SEPTIBBLE_(N1, N2, N3, N4, N5, N6, N7), _CAT_(__HEX_, N8))

En hier is Renato’s voorbeeld:

char b = _BYTE_(0100, 0001); /* equivalent to b = 65; or b = 'A'; or b = 0x41; */
unsigned int w = _WORD_(1101, 1111, 0100, 0011); /* equivalent to w = 57155; or w = 0xdf43; */
unsigned long int dw = _DWORD_(1101, 1111, 0100, 0011, 1111, 1101, 0010, 1000); /* Equivalent to dw = 3745774888; or dw = 0xdf43fd28; */

Antwoord 17

Gebruik gewoon de standaardbibliotheek in C++:

#include <bitset>

Je hebt een variabele van het type std::bitset:

. nodig

std::bitset<8ul> x;
x = std::bitset<8>(10);
for (int i = x.size() - 1; i >= 0; i--) {
      std::cout << x[i];
}

In dit voorbeeld heb ik de binaire vorm van 10opgeslagen in x.

8uldefinieert de grootte van je bits, dus 7ulbetekent zeven bits enzovoort.


Antwoord 18

Hier is mijn functie zonder Boost-bibliotheek toe te voegen:

gebruik: BOOST_BINARY(00010001);

int BOOST_BINARY(int a){
    int b = 0;
    for (int i = 0;i < 8;i++){
        b += a % 10 << i;
        a = a / 10;
    }
    return b;
}

Antwoord 19

Vanaf C++ 14 kunt u binaire literalen gebruiken, nu maken ze deel uit van de taal:

unsigned char a = 0b00110011;

Antwoord 20

C++ biedt een standaard sjabloon met de naam std::bitset. Probeer het als je wilt.


Antwoord 21

Gebruik: binair (00010001);

int binary (int a) {
int b = 0;

for (int i = 0;i < 8;i++){
    b += a % 10 << i;
    a = a / 10;
}
return b;

}


Antwoord 22

U kunt proberen een reeks bool:

te gebruiken

bool i[8] = {0,0,1,1,0,1,0,1}

Other episodes