数値をバイナリ形式で(coutを使用して)印刷する方法は?


215

私はオペレーティングシステムに関する大学のコースをフォローしており、バイナリから16進数、10進数から16進数などに変換する方法を学習しています。今日は、2の補数(〜number + 1)。

紙で行う演習が2つあります。課題を教師に提出する前に、回答を確認できるようにしたいと思います。最初の数回の演習用にC ++プログラムを作成しましたが、次の問題で自分の答えを確認する方法がわからなくなりました。

char a, b;

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

b = a >> 3;

我々はバイナリ表現を示すために必要なメモリ内のをabc

私はそれを紙の上で行いました、そしてそれは私に次の結果を与えます(2の補数の後の数の記憶のすべてのバイナリ表現):

a = 00111010(これは文字なので、1バイトです)

b = 00001000(これは文字なので、1バイトです)

c = 11111110 11000101(短いので2バイト)

私の答えを確認する方法はありますか?C ++で数値のメモリにバイナリ表現を表示する標準的な方法はありますか、または各ステップを自分でコーディングする必要がありますか(2の補数を計算してからバイナリに変換します)?後者はそれほど長くはかからないでしょうが、標準的な方法があるかどうか知りたいです。


2
あなたは16進数表現を理解していますか?もしそうなら、(を使用してstd::hex)16進表記を印刷できます
Nim

3
あなたは「インメモリ」を強調していますが、エンディアンの問題に対処していないことを願っています。
Mark Ransom

エンディアンとは何か知っていますか?もしそうなら、この演習ではそれを気にしますか?これらの質問への回答は、質問への回答に影響する場合があります。
R.マルティーニョフェルナンデス

IDEによっては、手書きのソリューションの正確さを確認するだけで、実際に役立つものを表示するプログラムを作成していない場合は、Visual Studioのメモリビューアーなどを使用して、メモリの正確な内容を表示できます。
Kiley Naro

1
Googleでもこれを実行します。たとえば、 - 58バイナリ」 –コードで自分で行う方法を知りたい場合は+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、2011

ビットセット値(この例ではxまたはy)をchar *に型キャストできますか?
nirvanaswap 2016年

1
Jerryに感謝します。to_string分後に発見しました。ちなみに、キャストは機能しません。ビットセット変数は、非常に難解に見える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進数として、または(ビットセットを介して)バイナリとしても出力できます。

#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)動作します。


11

C ++でメモリ内の数値のバイナリ表現を表示する標準的な方法はありますか[...]?

いいえstd::binstd::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.マルティーニョフェルナンデス

@ R.MartinhoFernandesのコメントに従って、sbiがΕύδοξοςの投稿を編集したようです。しかし、彼は最後の文を変更しませんでした。編集します。
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 2018

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 '28

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 2018

-11

これはあなたが探しているものですか?

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

30
モデレーターのメモこの回答に基づいて敵対的またはその他の非建設的なコメントを選択的に削除しようとしましたが、会話が途方に暮れてしまいました。すべてのコメントが削除されました。コメントは専門的で建設的で、何よりもトピックについてください。OPがこれを削除したい場合、OPは今までにそれを削除していたでしょう。この回答に同意しない場合は、投票してください。この回答を改善できる場合は、編集してください。</argument>。本当に、私たちは大人ですよね?私はほとんど誰もが13を超えていた作るために、ここでコメントしたことすべてに年齢を確認
ティム・ポスト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.