Como imprimir (usando o cout) a forma como um número é armazenado na memória?

Estou a seguir um curso universitário sobre sistemas operacionais e estamos a aprender a converter de binário para hexadecimal, decimal para hexadecimal, etc. e hoje acabamos de aprender como os números assinados/não assinados são armazenados na memória usando o complemento dos dois (~número + 1).

Temos alguns exercícios para fazer no papel e gostaria de poder verificar as minhas respostas antes de submeter o meu trabalho ao professor. Eu escrevi um programa C++ para os primeiros exercícios, mas agora estou preso a como pude verificar a minha resposta com o seguinte problema:

char a, b;

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

b = a >> 3;

E precisamos mostrar a representação binária na memória de a, b e c.

eu fiz isso no papel e isso me dá os seguintes resultados (Todas as representações binárias em memória dos números após o complemento dos dois):

a = 00111010 (é um char, so 1 byte)

B = 00001000 (é um char, por isso 1 byte)

C = 11111110 11000101 (é um curto, por isso 2 bytes)

Há alguma maneira de verificar a minha resposta? Existe uma maneira padrão em C++ para mostrar a representação binária em memória de um número, ou tenho que codificar cada passo eu mesmo (calcular o complemento dos dois e, em seguida, converter para binário)? Sei que esta última não demoraria muito, mas estou curioso se há uma maneira normal de o fazer.

Author: Yu Hao, 2011-09-08

9 answers

A maneira mais fácil é provavelmente criar um std::bitset representando o valor, então transfira isso para cout.

#include <bitset>
...

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

short c = -315;
std::bitset<16> y(c);
std::cout << y;
 316
Author: Jerry Coffin, 2013-08-09 21:53:02

Utilizar a conversão em voo para std::bitset. Sem variáveis temporárias, sem loops, sem funções, sem macros.

Ao Vivo Em Coliru

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

Impressões Digitais:

a = 11000110
b = 11111000
c = 1111111011000101
 84
Author: r233967, 2016-11-04 10:34:09

Se quiser mostrar a representação de bits de qualquer objecto, e não apenas um inteiro, lembre-se de reinterpretar primeiro como uma matriz de caracteres, então poderá imprimir o conteúdo dessa matriz, como hex, ou mesmo como binário (via bitset):

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

Note que os sistemas mais comuns são pouco-endianos, por isso a saída de show_binrep(c) é não os 1111111 01100010101 que você espera, porque não é assim que é armazenado na memória. Se você está procurando por valor representação em binário, então um simples cout << bitset<16>(c) funciona.

 23
Author: Cubbi, 2011-09-08 14:40:53

Semelhante ao que já foi publicado, apenas usando bit-shift e máscara para obter o bit; utilizável para qualquer tipo, sendo um modelo (só Não tenho certeza se existe uma maneira padrão de obter o número de bits em 1 byte, eu usei 8 aqui).

#include<iostream>

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);
    }
}
 6
Author: eudoxos, 2011-09-08 15:09:45

Existe uma forma padrão em C++ para mostrar a representação binária em memória de um número [...]?

Não. Não há nenhum {[[0]}, como std::hex ou std::dec, mas não é difícil emitir um binário numérico:

Você emite o bit mais à esquerda, mascarando todos os outros, o turno da esquerda, e repete isso para todos os bits que você tem.

(O número de bits num tipo é sizeof(T) * CHAR_BIT.)

 6
Author: sbi, 2015-08-02 13:16:02

Função Reutilizável:

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

Utilização:

int main(){
  uint16_t x=8;
  std::cout << toBinaryString(x);
}
Isto funciona com todo o tipo de inteiros.
 2
Author: ShitalShah, 2018-09-11 00:02:31
#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
Author: WriteYour NameHere, 2015-11-16 20:54:57

Aqui está a verdadeira maneira de obter uma representação binária de um número:

unsigned int i = *(unsigned int*) &x;
 -4
Author: user5463518, 2016-06-08 11:46:07
É disto que estás à procura?
std::cout << std::hex << val << std::endl;
 -7
Author: Kevin, 2011-09-08 14:33:50