245 votes

Puis-je utiliser un littéral binaire en C ou C ++?

Je dois travailler avec un nombre binaire.

J'ai essayé d'écrire:

 const x = 00010000 ;
 

Mais ça n'a pas marché.

Je sais que je peux utiliser un nombre hexadécimal qui a la même valeur que 00010000 mais je veux savoir s'il y a un type en C ++ pour les nombres binaires et s'il n'y en a pas, y a-t-il une autre solution pour mon problème?

329voto

qrdl Points 17813

Si vous utilisez GCC, vous pouvez utiliser l' extension GCC pour ceci:

 int x = 0b00010000;
 

76voto

wilhelmtell Points 25504
 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';
 

Le chiffre le plus à gauche du littéral doit toujours être 1, mais néanmoins.

72voto

vladr Points 34562

Vous pouvez utiliser BOOST_BINARY lors de l'attente pour C++0x. :) BOOST_BINARY sans doute a un avantage sur l'implémentation du modèle dans la mesure où il peut être utilisé dans des programmes C ainsi (c'est 100% de préprocesseur.)

Mise à JOUR

Pour faire l'inverse (c'est à dire imprimer un nombre sous forme binaire), vous pouvez utiliser la non-portable itoa de la fonction, ou mettre en place votre propre.

Malheureusement, vous ne pouvez pas faire de base 2 mise en forme avec STL flux (depuis setbase uniquement honneur bases 8, 10 et 16), mais vous pouvez utiliser soit une std::string version itoa, ou (le plus concis tout en étant légèrement moins efficace) std::bitset.

(Merci Roger pour l' bitset astuce!)

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

produit:

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

Lire aussi Herb Sutter est La Chaîne de Formatage de Manor Farm pour une discussion intéressante.

35voto

Renato Chandelier Points 131

Quelques compilateurs (généralement du Microcontrôleur) dispose d'une fonction spéciale mis en œuvre au sein de reconnaître littérale des nombres binaires par le préfixe "0b..." précédant le numéro, bien que la plupart des compilateurs C/C++ normes) n'ont pas cette fonctionnalité et, si c'est le cas, ici c'est ma solution alternative:

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

Inconvénients: (c'est pas un gros)
- Les nombres binaires doivent être regroupés en 4 par 4;
- Le binaire littéraux doivent être uniquement des nombres entiers non signés;

Avantages:
- Total préprocesseur de conduit, pas de spending processor time dans inutile d'opérations (like "?.. :..", "<<", "+") pour le programme exécutable (elle peut être réalisée centaine de fois dans l'application finale);
- Il fonctionne "mainly in C" compilateurs et C++ (template+enum solution works only in C++ compilers);
- Il a seulement la limitation des "longness" pour exprimer la "constante littérale" des valeurs. Il y aurait eu earlyish longness limitation (généralement de 8 bits:0 à 255) si l'on avait exprimé des valeurs constantes par l'analyse de résoudre des "enum solution"(usually 255 = reach enum definition limit), autrement, "constante littérale de" limitations, dans le compilateur permet à un plus grand nombre;
- Quelques autres solutions de la demande exagérée nombre de définitions de constantes (trop de définir est à mon avis), y compris à longue ou several header files (dans la plupart des cas pas facilement lisible et compréhensible, et le projet de devenir inutilement confus et prolongée, comme celle à l'aide de "BOOST_BINARY()");
- La simplicité de la solution: simple, lisible, compréhensible et réglable pour d'autres cas (pourrait être étendu pour le groupement de 8 par 8);

J'espère que cela aide, merci. Renato Lustre.

21voto

Federico A. Ramponi Points 23106

Ce fil peut aider.

Ça marche ! (Tous les crédits vont à Tom Torfs.)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X