이진 형식으로 숫자를 인쇄 (cout 사용)하는 방법은 무엇입니까?


215

나는 운영 체제에 관한 대학 과정을 따르고 있으며 바이너리에서 16 진수, 10 진수에서 16 진수 등으로 변환하는 방법을 배우고 있습니다. 오늘 우리는 2의 보수 (~ 숫자를 사용하여 부호있는 / 부호없는 숫자가 메모리에 저장되는 방법을 배웠습니다. + 1).

우리는 종이에 대해 몇 가지 연습을하고 있으며, 선생님 께 과제를 제출하기 전에 답을 확인하고 싶습니다. 처음 몇 가지 연습을 위해 C ++ 프로그램을 작성했지만 이제 다음 문제로 답을 확인하는 방법에 갇혀 있습니다.

char a, b;

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

b = a >> 3;

우리는 이진 표현 보여줄 필요가 메모리 의를 a, b하고 c.

나는 종이에 그것을 작성했고 나에게 다음과 같은 결과를 준다 (2의 보수 후 숫자의 메모리에있는 모든 이진 표현) :

a = 00111010 (문자이므로 1 바이트)

b = 00001000 (문자이므로 1 바이트)

c = 11111110 11000101 (짧으므로 2 바이트)

내 답변을 확인하는 방법이 있습니까? C ++에서 숫자의 메모리에 이진 표현을 표시하는 표준 방법이 있습니까, 아니면 각 단계를 직접 코딩해야합니까 (두 보수를 계산 한 다음 이진으로 변환해야합니까)? 나는 후자가 오래 걸리지 않는다는 것을 알고 있지만 표준 방법이 있는지 궁금합니다.


2
16 진 표현을 이해하십니까? 당신이 할 경우, 당신은 ( std::hex) 조작자를 사용하여 16 진수 표현을 인쇄 할 수 있습니다 -나는 당신이 나머지를 해결하기위한 연습으로 남겨 두겠습니다 ...
Nim

3
"메모리에"를 많이 강조하지만 엔디안 문제를 다루지 않기를 바랍니다.
Mark Ransom

엔디안이 무엇인지 알고 있습니까? 그렇다면이 운동에 관심이 있습니까? 이러한 질문에 대한 답변은 질문에 대한 답변에 영향을 줄 수 있습니다.
R. Martinho Fernandes

IDE에 따라 손으로 작성한 솔루션의 정확성을 확인하고 실제로 유용한 것을 표시하는 프로그램을 작성하지 않는 경우 Visual Studio의 메모리 뷰어와 같은 것을 사용하여 메모리의 정확한 내용을 볼 수 있습니다.
Kiley Naro

1
구글조차도 이진법 ( 예 : "-58 in binary") 을 수행하지만 코드에서 직접 수행하는 방법을 알아 보려면 +1입니다.
Konrad Rudolph

답변:


419

가장 쉬운 방법은 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';

23
아, 나는 계속 잊고있다 std::bitset! +1나에게서.
sbi

2
내 무지를 실례하지만 이것은 숫자의 이진 표현 (예 : 8은 00001000) 또는 메모리 표현 (예 : 부호 비트를 처리하고 "2의 보수"를 사용하여 -8을 저장하는 방법) 만 표시합니까?
Jesse Emond

12
@Jesse : bitset의 생성자 인수는 부호없는 값으로 해석되며 2의 보수와 동일하게 작동합니다. 엄밀히 말하면 C ++은 2의 보수 산술을 보장하지 않으며 -58 >> 3예제 의 연산 도 정의되어 있지 않습니다.
Potatoswatter

비트 세트 값 (예 : x 또는 y)을 char *로 타입 캐스트 할 수 있습니까?
nirvanaswap

1
감사합니다 Jerry, 몇 분 후에 to_string을 발견했습니다. 참고로, 캐스팅이 작동하지 않고 bitset 변수는 실제로 비전하게 보이는 bitset3ul (?!) 클래스의 객체입니다. 추상화가 작동하도록하는 것이 가장 좋습니다!
nirvanaswap

102

로 즉시 변환을 사용하십시오 std::bitset. 임시 변수, 루프, 함수, 매크로가 없습니다.

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

인쇄물:

a = 11000110
b = 11111000
c = 1111111011000101

6
하드 코딩 크기는 필요하지 않습니다. 예 : 인쇄 x용도 : std::cout << std::bitset<8*sizeof(x)>(x).
Apollys 모니카 지원

25

정수뿐만 아니라 객체의 비트 표현을 표시하려면 먼저 char 배열로 재 해석 한 다음 해당 배열의 내용을 16 진수 또는 2 진 (비트 세트를 통해)으로 인쇄해야합니다.

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

대부분의 일반적인 시스템은 리틀 엔디안이므로 출력은 메모리에 저장되는 방식이 아니기 때문에 1111111 011000101 show_binrep(c)아닙니다 . 이진법으로 가치 표현을 찾고 있다면 간단한 cout << bitset<16>(c)작동입니다.


11

C ++에서 숫자의 메모리에 이진 표현을 나타내는 표준 방법이 있습니까 [...]?

호 아무 없다 std::bin처럼, std::hex또는 std::dec,하지만 자신 바이너리 출력에 하드 숫자 아니다 :

다른 모든 비트를 마스킹하고 왼쪽 시프트 한 다음 모든 비트에 대해 반복하여 가장 왼쪽 비트를 출력합니다.

(타입의 비트 수는 sizeof(T) * CHAR_BIT입니다.)


7

이미 게시 된 것과 유사하게 비트 시프트 및 마스크를 사용하여 비트를 얻습니다. 템플릿 인 모든 유형에 사용할 수 있습니다 ( 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);
    }
}

3
바이트 당 비트 수를 얻는 표준 방법은 매크로 CHAR_BIT입니다.
R. Martinho Fernandes

sbi는 @ R.MartinhoFernandes의 의견에 따라 Εύδοξος의 게시물을 편집 한 것으로 보입니다. 그러나 그는 마지막 문장을 바꾸지 않았습니다. 편집하겠습니다.
gsamaras

3

재사용 가능한 기능 :

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

이것은 모든 종류의 정수에서 작동합니다.


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

해서는 안 int t = pow(2, num_of_bits - 1);됩니까?
BmyGuest

0

이전 C ++ 버전을 사용하면이 스 니펫을 사용할 수 있습니다.

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

잘못된 비트 수를 인쇄합니다. 111 000 110 9 비트 아닌 8 인
데이비드 원장

내가 경계 실수를 지금 확인하세요
Ratah

0

std :: bitset 답변 및 편의 템플릿 사용 :

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

다음과 같이 사용하십시오.

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;

출력을 생성합니다.

c: A binary: 01000001
x: 1234 binary: 00000000000000000000010011010010
z: -1024 binary: 1111111111111111111111111111111111111111111111111111110000000000

-5

숫자의 이진 표현을 얻는 진정한 방법은 다음과 같습니다.

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

아니 ; 이것은 x를 i에 복사합니다. 이것을 농담으로하지 않았다면?
AnthonyD973

-11

찾고 계십니까?

std::cout << std::hex << val << std::endl;

30
사회자 노트 나는 이 답변에 따라 적대적이거나 비 건설적인 의견을 선택적으로 제거 하려고했고 , 결국 매우 깨진 대화로 끝났다. 모든 의견이 삭제되었습니다. 전문적이고 건설적이며 무엇보다도 주제에 대한 의견을 유지하십시오. OP가이를 제거하려면 OP가이를 제거했을 것입니다. 이 답변에 동의하지 않으면 투표하십시오. 이 답변을 개선 할 수 있으면 편집하십시오. </argument>. 정말, 우리는 성인입니다. 나는 모든 사람들이 13 세 이상인지 확인하기 위해 여기에 언급 된 모든 연령대를 거의 점검했습니다.
Tim Post
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.