Jak wydrukować (za pomocą cout) liczbę w postaci binarnej?

Jestem po studiach na temat systemów operacyjnych i uczymy się, jak konwertować z binarnych do szesnastkowych, dziesiętnych do szesnastkowych itp. dzisiaj dowiedzieliśmy się, w jaki sposób podpisane / niepodpisane liczby są przechowywane w pamięci za pomocą dopełniacza (~liczba + 1).

Mamy kilka ćwiczeń do wykonania na papierze i chciałbym być w stanie zweryfikować moje odpowiedzi przed przesłaniem pracy do nauczyciela. Napisałem program C++ do pierwszych kilku ćwiczeń, ale teraz jestem przyklejony, Jak mogę zweryfikować moją odpowiedź z następującym problemem:

char a, b;

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

b = a >> 3;

I musimy pokazać binarną reprezentację w pamięci z a, b i c.

Zrobiłem to na papierze i daje mi następujące wyniki (wszystkie reprezentacje binarne w pamięci liczb po dopełnieniu dwóch):

A = 00111010 (jest to znak, więc 1 bajt)

B = 00001000 (jest to znak, więc 1 bajt)

C = 11111110 11000101 (jest krótki, więc 2 bajtów)

Czy istnieje sposób, aby zweryfikować moją odpowiedź? Czy istnieje standardowy sposób w C++, aby pokazać binarną reprezentację w pamięci liczby, czy też muszę sam kodować każdy krok (obliczyć dopełniacz dwóch i następnie przekonwertować na binarny)? Wiem, że to drugie nie potrwa długo, ale jestem ciekaw, czy istnieje standardowy sposób, aby to zrobić.

Author: Community, 2011-09-08

12 answers

Najprostszym sposobem jest prawdopodobnie stworzenie std::bitset reprezentując wartość, następnie streamuj ją do 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';
 466
Author: Jerry Coffin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-12 19:14:55

Użyj konwersji on-the-fly do std::bitset. Brak zmiennych tymczasowych, pętli, funkcji, makr.

Live On 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;
}

Druki:

a = 11000110
b = 11111000
c = 1111111011000101
 117
Author: r233967,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-04 10:34:09

Jeśli chcesz wyświetlić reprezentację bitową dowolnego obiektu, a nie tylko liczby całkowitej, pamiętaj, aby najpierw reinterpretować jako tablicę znaków, wtedy możesz wydrukować zawartość tej tablicy, jako hex, lub nawet jako binarną (poprzez 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);
}

Zauważ, że większość popularnych systemów to little-endian, więc wyjście show_binrep(c) to , a nie 1111111 011000101, ponieważ nie jest tak przechowywane w pamięci. Jeśli szukasz wartości reprezentacji w binarnym, to proste cout << bitset<16>(c) działa.

 24
Author: Cubbi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-08 14:40:53

Czy istnieje standardowy sposób w C++, aby pokazać binarną reprezentację w pamięci liczby [...]?

Nie. Nie ma std::bin, jak std::hex lub std::dec, ale nie jest trudno samemu wypisać liczbę binarną:

Wypisujesz najbardziej lewy bit, maskując wszystkie pozostałe, lewy shift i powtarzasz to dla wszystkich bitów, które masz.

(liczba bitów w typie to sizeof(T) * CHAR_BIT.)

 13
Author: sbi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-02 13:16:02

W C++20 będziesz mógł używać std::format aby to zrobić:

unsigned char a = -58;
std::cout << std::format("{:b}", a);

Wyjście:

11000110

W międzyczasie możesz skorzystać z biblioteki {fmt} , std::format jest oparty na. {fmt} zapewnia również funkcję print, która sprawia, że jest to jeszcze łatwiejsze i bardziej wydajne (godbolt):

unsigned char a = -58;
fmt::print("{:b}", a);

Disclaimer: jestem autorem {fmt} i C++20 std::format.

 12
Author: vitaut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-16 20:50:41

Podobne do tego, co jest już opublikowane, po prostu za pomocą bit-shift i mask, aby uzyskać bit; użyteczny dla każdego typu, będąc szablonem (Tylko Nie wiem, czy istnieje standardowy sposób, aby uzyskać liczbę bitów w 1 bajcie, użyłem 8 tutaj ).

#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);
    }
}
 6
Author: eudoxos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-31 10:40:34

Funkcja wielokrotnego użytku:

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

Użycie:

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

To działa z wszystkimi rodzajami liczb całkowitych.

 4
Author: Shital Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-16 20:54:57

Używając starej wersji C++, możesz użyć tego fragmentu:

template<typename T>
string toBinary(const T& t)
{
  string s = "";
  int n = sizeof(T)*8;
  for(int i=n-1; 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 = => 11000110
b = => 11111000
c = -315 => 1111111011000101
 0
Author: Ratah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-28 16:08:29

Używanie std:: bitset odpowiedzi i szablonów wygody:

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

template<typename T>
struct BinaryForm {
    BinaryForm(const T& v) : _bs(v) {}
    const std::bitset<sizeof(T)*CHAR_BIT> _bs;
};

template<typename T>
inline std::ostream& operator<<(std::ostream& os, const BinaryForm<T> bf) {
    return os << bf._bs;
}

Używanie go w ten sposób:

auto c = 'A';
std::cout << "c: " << c << " binary: " << BinaryForm{c} << std::endl;
unsigned x = 1234;
std::cout << "x: " << x << " binary: " << BinaryForm{x} << std::endl;
int64_t z { -1024 };
std::cout << "z: " <<  << " binary: " << BinaryForm{z} << std::endl;

Generuje wyjście:

c: A binary: 01000001
x: 1234 binary: 00000000000000000000010011010010
z: -1024 binary: 1111111111111111111111111111111111111111111111111111110000000000
 0
Author: user5673656,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-02 03:40:14

Oto prawdziwy sposób, aby uzyskać binarną reprezentację liczby:

unsigned int i = *(unsigned int*) &x;
 -5
Author: user5463518,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-08 11:46:07

Tego szukasz?

std::cout << std::hex << val << std::endl;
 -11
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-08 14:33:50