web-dev-qa-db-fra.com

Comment imprimer (en utilisant cout) un nombre sous forme binaire?

Je suis un cours collégial sur les systèmes d'exploitation et nous apprenons à convertir binaire en hexadécimal, décimal en hexadécimal, etc. + 1).

Nous avons quelques exercices à faire sur papier et j'aimerais pouvoir vérifier mes réponses avant de soumettre mon travail à l'enseignant. J'ai écrit un programme C++ pour les premiers exercices, mais je ne sais plus comment vérifier ma réponse avec le problème suivant:

char a, b;

short c;
a = -58;
c = -315;

b = a >> 3;

et nous devons montrer la représentation binaire en mémoire de a, b et c.

Je l'ai fait sur papier et cela me donne les résultats suivants (toutes les représentations binaires en mémoire des nombres après le complément à deux):

a = 00111010 (c'est un caractère, donc 1 octet)

b = 00001000 (c'est un caractère, donc 1 octet)

c = 11111110 11000101 (c'est un court, donc 2 octets)

Y a-t-il un moyen de vérifier ma réponse? Existe-t-il une méthode standard en C++ pour afficher la représentation binaire en mémoire d'un nombre, ou dois-je coder chaque étape moi-même (calculer le complément à deux, puis convertir en binaire)? Je sais que ce dernier ne prendrait pas autant de temps, mais je suis curieux de savoir s'il existe un moyen standard de le faire.

189
Jesse Emond

Le moyen le plus simple est probablement de créer un std::bitset représentant la valeur, puis de le transmettre à cout.

_#include <bitset>
...

char a = -58;    
std::bitset<8> x(a);
std::cout << x << '\n';

short c = -315;
std::bitset<16> y(c);
std::cout << y << '\n';
_
367
Jerry Coffin

Utilisez la conversion à la volée en std::bitset. Pas de variables temporaires, pas de boucles, pas de fonctions, pas de macros.

Live On Colir

#include <iostream>
#include <bitset>

int main() {
    int a = -58, b = a>>3, c = -315;

    std::cout << "a = " << std::bitset<8>(a)  << std::endl;
    std::cout << "b = " << std::bitset<8>(b)  << std::endl;
    std::cout << "c = " << std::bitset<16>(c) << std::endl;
}

Impressions:

a = 11000110
b = 11111000
c = 1111111011000101
93
r233967

Si vous souhaitez afficher la représentation en bits de n'importe quel objet, et pas seulement d'un entier, n'oubliez pas de réinterpréter d'abord sous forme de tableau de caractères. Vous pouvez ensuite imprimer le contenu de ce tableau, en tant qu'hex ou même en tant que binaire (via un jeu de bits):

#include <iostream>
#include <bitset>
#include <climits>

template<typename T>
void show_binrep(const T& a)
{
    const char* beg = reinterpret_cast<const char*>(&a);
    const char* end = beg + sizeof(a);
    while(beg != end)
        std::cout << std::bitset<CHAR_BIT>(*beg++) << ' ';
    std::cout << '\n';
}
int main()
{
    char a, b;
    short c;
    a = -58;
    c = -315;
    b = a >> 3;
    show_binrep(a);
    show_binrep(b);
    show_binrep(c);
    float f = 3.14;
    show_binrep(f);
}

Notez que la plupart des systèmes courants sont little-endian, donc le résultat de show_binrep(c) est pas le 1111111 011000101 que vous attendez, car ce n'est pas ainsi qu'il est stocké en mémoire. Si vous recherchez une représentation de valeur en binaire, un simple cout << bitset<16>(c) fonctionne.

23
Cubbi

Existe-t-il un moyen standard en C++ d'afficher la représentation binaire en mémoire d'un nombre [...]?

Non, il n'y a pas de std::bin, comme std::hex ou std::dec, mais il n'est pas difficile de générer vous-même un nombre binaire:

Vous produisez le bit le plus à gauche en masquant tous les autres, le décalage à gauche et répétez cela pour tous les bits que vous avez.

(Le nombre de bits dans un type est sizeof(T) * CHAR_BIT.)

7
sbi

Semblable à ce qui est déjà posté, il suffit d’utiliser le bit-shift et le masque pour obtenir le bit; utilisable pour tout type, étant un template (seulement pas sûr s'il existe un moyen standard d'obtenir le nombre de bits dans 1 octet, j'ai utilisé 8 ici).

#include<iostream>
#include <climits>

template<typename T>
void printBin(const T& t){
    size_t nBytes=sizeof(T);
    char* rawPtr((char*)(&t));
    for(size_t byte=0; byte<nBytes; byte++){
        for(size_t bit=0; bit<CHAR_BIT; bit++){
            std::cout<<(((rawPtr[byte])>>bit)&1);
        }
    }
    std::cout<<std::endl;
};

int main(void){
    for(int i=0; i<50; i++){
        std::cout<<i<<": ";
        printBin(i);
    }
}
7
eudoxos

Fonction réutilisable:

template<typename T>
static std::string toBinaryString(const T& x)
{
    std::stringstream ss;
    ss << std::bitset<sizeof(T) * 8>(x);
    return ss.str();
}

tilisation:

int main(){
  uint16_t x=8;
  std::cout << toBinaryString(x);
}

Cela fonctionne avec tout type d’entiers.

3
Shital Shah
#include <iostream> 
#include <cmath>       // in order to use pow() function
using namespace std; 

string show_binary(unsigned int u, int num_of_bits);

int main() 
{ 

  cout << show_binary(128, 8) << endl;   // should print 10000000
  cout << show_binary(128, 5) << endl;   // should print 00000
  cout << show_binary(128, 10) << endl;  // should print 0010000000

  return 0; 
}

string show_binary(unsigned int u, int num_of_bits) 
{ 
  string a = "";

  int t = pow(2, num_of_bits);   // t is the max number that can be represented

  for(t; t>0; t = t/2)           // t iterates through powers of 2
      if(u >= t){                // check if u can be represented by current value of t
          u -= t;
          a += "1";               // if so, add a 1
      }
      else {
          a += "0";               // if not, add a 0
      }

  return a ;                     // returns string
}
1

En utilisant l'ancienne version C++, vous pouvez utiliser cet extrait:

template<typename T>
string toBinary(const T& t)
{
  string s = "";
  int n = sizeof(T)*8;
  for(int i=n; i>=0; i--)
  {
    s += (t & (1 << i))?"1":"0";
  }
  return s;
}

int main()
{
  char a, b;

  short c;
  a = -58;
  c = -315;

  b = a >> 3;

  cout << "a = " << a << " => " << toBinary(a) << endl;
  cout << "b = " << b << " => " << toBinary(b) << endl;
  cout << "c = " << c << " => " << toBinary(c) << endl;
}

a = ã => 111000110
b = ° => 111111000
c = -315 => 11111111011000101
0
Ratah