Вопрос

Я иду в колледже об операционных системах и учимся преобразовать из бинарного в шестнадцатеричную, десятичную в шестнадцатеричную и т. Д. И сегодня мы только что узнали, как подписанные/неподписанные цифры хранятся в памяти, используя дополнение двух (~ число + 1).

У нас есть пара упражнений на бумаге, и я хотел бы иметь возможность проверить свои ответы, прежде чем отправить свою работу учителю. Я написал программу C ++ для первых нескольких упражнений, но теперь я застрял в том, как я мог бы проверить свой ответ следующей проблемой:

char a, b;

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

b = a >> 3;

и нам нужно показать двоичное представление в памяти из a, b а также c.

Я сделал это на бумаге, и это дает мне следующие результаты (все двоичные представления в память о числах после дополнения двух):

a = 00111010 (это символ, так что 1 байт)

b = 00001000 (это символ, так что 1 байт)

c = 11111110 11000101 (это короткое, так что 2 байта)

Есть ли способ проверить мой ответ? Есть ли стандартный способ в C ++, чтобы показать двоичное представление в память о числе, или мне нужно кодировать каждый шаг сам (рассчитайте дополнение двух, а затем конвертируется в двоичный)? Я знаю, что последнее не займет так много времени, но мне любопытно, есть ли стандартный способ сделать это.

Это было полезно?

Решение

Самый простой способ - это создать std::bitset представляя значение, затем передавать его на 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';

Другие советы

Используйте преобразование на лету в std::bitset. Анкет Нет временных переменных, без петлей, нет функций, без макросов.

Живи на Колиру

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

Отпечатки:

a = 11000110
b = 11111000
c = 1111111011000101

Если вы хотите отобразить битовое представление любого объекта, а не просто целого числа, не забудьте сначала переосмыслить как массив, то вы можете распечатать содержимое этого массива, как Hex или даже бинарный (через 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);
}

Обратите внимание, что большинство распространенных систем являются маленькими эндианскими, поэтому выход show_binrep(c) является нет Вы ожидаете 1111111 011000101, потому что это не то, как он хранится в памяти. Если вы ищете ценность представление в бинарном, затем простое cout << bitset<16>(c) работает.

Есть ли стандартный способ в C ++, чтобы показать бинарное представление в память о числе [...]?

Нет. std::bin, как std::hex или же std::dec, но не сложно вывести число двоичного из бинара:

Вы выводите левый бит, маскируя все остальные, левой смену и повторяете это для всех ваших битов.

(Количество битов в типе sizeof(T) * CHAR_BIT.)

Подобно тому, что уже опубликовано, просто используя битовые сдвиги и маски, чтобы получить бит; можно использовать для любого типа, будучи шаблоном (Только не уверен, есть ли стандартный способ получить количество бит за 1 байт, я использовал 8 здесь).

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

Многоразовая функция:

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

Применение:

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

Это работает со всеми видами целых чисел.

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

Используя старую версию C ++, вы можете использовать этот фрагмент:

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

Вот истинный способ получить бинарное представление числа:

unsigned int i = *(unsigned int*) &x;

Это то, что вы ищете?

std::cout << std::hex << val << std::endl;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top