Kann ich ein binäres Literal in C oder C++ verwenden?

Lesezeit: 10 Minuten

Kann ich ein binares Literal in C oder C verwenden
hamza

Ich muss mit einer binären Zahl arbeiten.

Ich habe versucht zu schreiben:

const x = 00010000;

Aber es hat nicht funktioniert.

Ich weiß, dass ich eine Hexadezimalzahl verwenden kann, die denselben Wert hat wie 00010000aber ich möchte wissen, ob es in C++ einen Typ für Binärzahlen gibt und wenn nicht, gibt es eine andere Lösung für mein Problem?

  • Du weißt, dass 00010000 ist oktal, oder? (Und Ihrer Deklaration fehlt ein Typ.)

    – Keith Thompson

    28. September 2011 um 2:32 Uhr

  • Hier moderner Weg mit C++ Literalen.

    – Lol4t0

    14. Mai 2013 um 16:11 Uhr

  • C++14 hat dafür eine Funktion hinzugefügt. Siehe meine neue Antwort für weitere Details unten. Natürlich benötigt es einen Compiler, der es implementiert.

    – lpapp

    24. Dezember 2013 um 3:20 Uhr


  • @FormlessCloud: Dies sind die in den C- und C++-Standards angegebenen Syntaxregeln (0b erscheint nur in C++14). Sie sind auf Eindeutigkeit ausgelegt.

    – Keith Thompson

    16. Oktober 2015 um 21:39 Uhr

  • Mögliches Duplikat von Binärliteralen?

    – MJ Rayburn

    9. November 2018 um 7:16 Uhr

Kann ich ein binares Literal in C oder C verwenden
qrdl

Wenn Sie GCC verwenden, können Sie verwenden eine GCC-Erweiterung (welches enthalten ist dem C++14-Standard) dafür:

int x = 0b00010000;

  • Mehrere andere Compiler haben diese oder ähnliche Möglichkeiten, Zahlen in Basis 2 auszudrücken.

    – Nategans

    12. April 2010 um 21:20 Uhr

  • Es wäre schön, dies standardisiert zu haben, aber clang unterstützt dieselbe Notation.

    – polemon

    11. April 2011 um 12:37 Uhr

  • Es funktioniert in Clang, GCC und TCC. Im PCC funktioniert es nicht. Ich habe keinen anderen Compiler zum Testen.

    – Michas

    20. Juni 2011 um 16:05 Uhr

  • Ich habe eine Reihe von Compilern für eingebettete Systeme gesehen, die dies unterstützen. Ich kenne keinen besonderen Grund, warum es keine Standardsprachfunktion sein sollte.

    – Superkatze

    1. August 2011 um 21:34 Uhr

  • @polmon open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3472.pdf (C++14.)

    – Jonathan Baldwin

    17. Januar 2014 um 11:21 Uhr

Kann ich ein binares Literal in C oder C verwenden
Muhammad Annaqeeb

Sie können binäre Literale verwenden. Sie sind in C++14 standardisiert. Zum Beispiel,

int x = 0b11000;

Unterstützung im GCC

Die Unterstützung in GCC begann in GCC 4.3 (siehe https://gcc.gnu.org/gcc-4.3/changes.html) als Erweiterungen der C-Sprachfamilie (vgl https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions), aber seit GCC 4.9 wird es jetzt entweder als C++14-Funktion oder als Erweiterung erkannt (siehe Unterschied zwischen GCC-Binärliteralen und C++14-Literalen?)

Unterstützung in Visual Studio

Die Unterstützung in Visual Studio wurde in Visual Studio 2015 Preview gestartet (siehe https://www.visualstudio.com/news/vs2015-preview-vs#C++).

  • Sie können ‘ verwenden, um jeden Teil zu trennen: “0b0000’0100’0100’0001

    – Camino

    6. Februar 2019 um 19:23 Uhr

  • @camino Schön, dass du den ersten verlieren kannst “

    – KeyC0de

    6. Oktober 2019 um 17:16 Uhr

  • Dies sollte die akzeptierte Antwort sein. Die meisten anderen Antworten sind sooo veraltet.

    – Alex

    24. Januar 2020 um 13:24 Uhr

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

Die ganz linke Stelle des Literals muss immer noch 1 sein, aber trotzdem.

  • Bessere Version: bitbucket.org/kniht/scraps/src/tip/cpp/binary.hpp (binary<10>::value == binary<010>::value und etwas Fehlerprüfung)

    Roger Pate

    10. April 2010 um 2:30 Uhr

  • Irgendwie verpasst, bevor ich meine eigene fast identische Antwort gepostet habe. Aber in meinem muss die führende Ziffer 0 sein, nicht 1.

    – Markieren Sie Lösegeld

    10. April 2010 um 3:50 Uhr


  • Eine bessere Version dieser Vorlagenidee: code.google.com/p/cpp-binary-constants

    – Valentin Galea

    13. Februar 2012 um 21:00 Uhr

  • @ValentinGalea – warum die Google-Version besser als diese?

    – AJed

    25. März 2016 um 2:01 Uhr

  • Das ist verdammt beeindruckend. Schade, dass es nicht für eine hohe Anzahl von Bits funktioniert.

    – Der Quantenphysiker

    18. April 2017 um 13:39 Uhr

1647076211 905 Kann ich ein binares Literal in C oder C verwenden
vladr

Du kannst verwenden BOOST_BINARY beim Warten auf C++0x. 🙂 BOOST_BINARY hat wohl insofern einen Vorteil gegenüber der Template-Implementierung kann auch in C-Programmen verwendet werden (Es ist zu 100 % präprozessorgesteuert.)

Um das Gegenteil zu tun (dh eine Zahl in binärer Form auszudrucken), können Sie das nicht-portable verwenden itoa Funktionoder selbst umsetzen.

Leider können Sie mit STL-Streams keine Base-2-Formatierung durchführen (seit setbase wird nur die Basen 8, 10 und 16 anerkennen), aber Sie kann Verwenden Sie entweder a std::string Version von itoaoder (je kürzer, aber geringfügig weniger effizient) 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;
}

produziert:

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

Lesen Sie auch Herb Sutters Die String-Formatierer von Manor Farm für eine interessante Diskussion.

1647076211 704 Kann ich ein binares Literal in C oder C verwenden
Kronleuchter Renato

Ein paar Compiler (normalerweise die für Mikrocontroller) verfügt über eine spezielle Funktion, die in der Erkennung von wörtlichen Binärzahlen von implementiert ist Präfix “0b…” vor der Zahl, obwohl die meisten Compiler (C/C++-Standards) keine solche Funktion haben, und wenn dies der Fall ist, hier ist meine alternative Lösung:

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

Nachteile (es ist nicht so groß):

  • Die Binärzahlen müssen 4 mal 4 gruppiert werden;
  • Die binären Literale dürfen nur vorzeichenlose Ganzzahlen sein;

Vorteile:

  • Insgesamt Präprozessor getrieben, nicht spending processor time in sinnlosen Operationen (like "?.. :..", "<<", "+") zum ausführbaren Programm (es kann in der endgültigen Anwendung hundertmal ausgeführt werden);
  • Es klappt "mainly in C" Compiler und auch C++ (template+enum solution works only in C++ compilers);
  • Es hat nur die Beschränkung der “Lange” zum Ausdrücken von “buchstäblichen konstanten” Werten. Es hätte eine frühe Längenbeschränkung (normalerweise 8 Bit: 0-255) gegeben, wenn man konstante Werte durch Parsing-Auflösung von ausgedrückt hätte "enum solution" (usually 255 = reach enum definition limit)anders, “literale Konstanten” Einschränkungen, im Compiler erlaubt größere Zahlen;
  • Einige andere Lösungen erfordern eine übertriebene Anzahl konstanter Definitionen (meiner Meinung nach zu viele Definitionen), einschließlich langer oder several header files (in den meisten Fällen nicht leicht lesbar und verständlich, und machen das Projekt unnötig konfus und langwierig, wie die Verwendung von "BOOST_BINARY()");
  • Einfachheit der Lösung: leicht lesbar, verständlich und für andere Fälle anpassbar (könnte auch für die Gruppierung 8 mal 8 erweitert werden);

  • Warum ist zB B_0100 nicht verwendet (statt 0100)? Wie in zB char b = BYTE(0100,0001);.

    – Peter Mortensen

    29. März 2017 um 16:09 Uhr

  • @PeterMortensen Das B_ wird von hinzugefügt _B2H Präprozessorfunktion.

    – mxmlnkn

    26. Oktober 2017 um 17:02 Uhr

Dieser Faden kann helfen.

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

Es klappt! (Alle Credits gehen an Tom Torfs.)

  • Warum ist zB B_0100 nicht verwendet (statt 0100)? Wie in zB char b = BYTE(0100,0001);.

    – Peter Mortensen

    29. März 2017 um 16:09 Uhr

  • @PeterMortensen Das B_ wird von hinzugefügt _B2H Präprozessorfunktion.

    – mxmlnkn

    26. Oktober 2017 um 17:02 Uhr

1647076211 790 Kann ich ein binares Literal in C oder C verwenden
SS Anne

Wie bereits beantwortet, haben die C-Standards keine Möglichkeit, Binärzahlen direkt zu schreiben. Es gibt jedoch Compiler-Erweiterungen, und anscheinend enthält C++14 die 0b Präfix für binär. (Beachten Sie, dass diese Antwort ursprünglich im Jahr 2010 veröffentlicht wurde.)

Eine beliebte Problemumgehung ist das Einschließen eine Header-Datei mit Hilfsmakros. Eine einfache Möglichkeit besteht auch darin, eine Datei zu generieren, die Makrodefinitionen für alle 8-Bit-Muster enthält, z.

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

Das ergibt nur 256 #defines, und wenn Binärkonstanten größer als 8 Bit benötigt werden, können diese Definitionen mit Verschiebungen und ODER kombiniert werden, möglicherweise mit Hilfsmakros (z. BIN16(B00000001,B00001010)). (Es ist nicht plausibel, individuelle Makros für jeden 16-Bit-, geschweige denn 32-Bit-Wert zu haben.)

Der Nachteil ist natürlich, dass diese Syntax das Schreiben aller führenden Nullen erfordert, aber dies kann sie auch für Anwendungen wie das Setzen von Bit-Flags und Inhalten von Hardware-Registern klarer machen. Informationen zu einem funktionsähnlichen Makro, das zu einer Syntax ohne diese Eigenschaft führt, finden Sie unter bithacks.h oben verlinkt.

  • Wie groß müsste also eine Datei sein, die der CPP lesen müsste, wenn Sie alle Makros für a hätten long long int?

    – wilhelmtel

    10. April 2010 um 2:03 Uhr

  • @wilhelmtell: Und was ist die Relevanz davon, wenn ich „alle 8 Bit Muster“ (= 256 Zeilen) und schlug vor, größere Mengen davon zu kombinieren? Sogar der BOOST_BINARY der akzeptierten Antwort definiert alle 8-Bit-Muster im Header…

    – Arkku

    10. April 2010 um 14:12 Uhr


  • Nicht sicher, ob Upvote oder Downvote. Einerseits ist es schlau, weil vor der Kompilierung eine einfache Textersetzung erfolgt. Und Sie können einfach einen Generator schreiben, um eine solche Header-Datei auch für Datentypen größer als 8-Bit zu erstellen. Andererseits weiß ich weder, wie viele #define ein Präprozessor verarbeiten kann, noch ob sie effizient verarbeitet werden können. Vielleicht ist es möglich, die Menge der notwendigen Definitionen zu reduzieren, indem Hilfsmakros für die Verkettung mit verwendet werden ##.

    – Tango

    9. März 2021 um 12:02 Uhr

  • @tangoal Wie ich in der Antwort sage, schlage ich dies nur für 8-Bit-Makros vor, und ich erkläre ausdrücklich, dass ich 16-Bit oder höher nicht für plausibel halte, und ich schlage auch vor, höhere Breiten (als 8 Bits) mit Hilfsmakros. Wenn Sie also ablehnen, hoffe ich, dass der Grund nicht derselbe ist wie “Ich habe die Antwort nicht gelesen, aber das funktioniert nicht für mehr als 8 Bit”, weil dies nicht beabsichtigt ist. =)

    – Arkku

    9. März 2021 um 13:37 Uhr


  • Was die Verkettung mit betrifft ##ich denke, das würde eine Syntax wie erfordern BIN16(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1) was meiner Meinung nach keine große Verbesserung gegenüber dem ist BIN16(B00000001,B00001010) in der Antwort vorgeschlagen. Oder hatten Sie eine andere Idee als eine dieser Grundformen? (Zugegeben, ein Editor mit intelligenter Autovervollständigung könnte bei der früheren Syntax helfen und die genau richtige Menge an Argumenten mit Platzhaltern versehen, was als Verbesserung angesehen werden könnte, obwohl es nicht so schön ist, mit der Hand zu tippen, wenn Sie bis 16 zählen müssen. )

    – Arkku

    9. März 2021 um 13:42 Uhr


993230cookie-checkKann ich ein binäres Literal in C oder C++ verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy