web-dev-qa-db-ja.com

C ++でintをバイナリ文字列表現に変換する方法

バイナリ文字列表現として保存したいintがあります。これはどのように行うことができますか?

15
neuromancer

これを試して:

#include <bitset>
#include <iostream>
int main()
{
    std::bitset<32>      x(23456);
    std::cout << x << "\n";


    // If you don't want a variable just create a temporary.
    std::cout << std::bitset<32>(23456) << "\n";
}
38
Martin York

最初に2進数に変換したいintがあります。

それは正確にはどういう意味ですか? 「2進数」のタイプはありません。非常に奇妙なコンピューターを使用していない限り、intはすでに内部的にバイナリ形式で表されていますが、これは実装の詳細です。概念的には、これは単なる整数です。

画面に数字を印刷するたびに、それを文字列に変換する必要があります。ほとんどのI/Oシステムは、人間がより簡単に時間を過ごせるように、このプロセスに10進表現を選択したことがあります。しかし、intについては本質的に10進数はありません。

とにかく、整数の基本b表現xを生成するには、次のアルゴリズムに従うだけです。

  1. 空の文字列でsを初期化します

  2. m = x % b

  3. x = x / b

  4. mを数字dに変換します。

  5. dsを追加します。

  6. xがゼロでない場合は、手順2に進みます。

  7. リバースs

ステップ4は、b <= 10で、コンピューターが0〜9の数字が連続している文字エンコードを使用している場合は簡単です。これは単にd = '0' + mだからです。それ以外の場合は、ルックアップテーブルが必要です。

必要なスペースが事前にわかっていて、文字列の右端から開始する場合は、手順5と7を簡略化して、dの左側にsを追加できます。

b == 2(バイナリ表現など)の場合、ステップ2はm = x & 1に簡略化でき、ステップ3はx = x >> 1に簡略化できます。

reverseを使用したソリューション:

#include <string>
#include <algorithm>

std::string binary(unsigned x)
{
    std::string s;
    do
    {
        s.Push_back('0' + (x & 1));
    } while (x >>= 1);
    std::reverse(s.begin(), s.end());
    return s;
}

reverseなしのソリューション:

#include <string>

std::string binary(unsigned x)
{
    // Warning: this breaks for numbers with more than 64 bits
    char buffer[64];
    char* p = buffer + 64;
    do
    {
        *--p = '0' + (x & 1);
    } while (x >>= 1);
    return std::string(p, buffer + 64);
}
14
fredoverflow

http://snippets.dzone.com/posts/show/4716 または http://www.phanderson.com/printer/bin_disp.html 2つの良い例です。

単純なアプローチの基本原則:

  • #が0になるまでループします
  • &(ビット単位および)#と1。結果(1または0)を文字列バッファーの最後に出力します。
  • >>=を使用して#を1ビットシフトします。
  • ループを繰り返す
  • 反転文字列バッファを出力します

文字列を逆にしたり、バッファ文字列の長さに合わせて#sに制限する必要がないようにするには、次のことができます。

  • 上限を計算する(log2(N))-Lと言う
  • マスクの計算= 2 ^ L
  • マスク== 0になるまでループします:
    • &(ビット単位および)#付きのマスク。結果(1または0)を出力します。
    • 番号&=(マスク-1)
    • マスク>> = 1(2で割る)
2
DVK

これは、拡張可能なハッシュに関する他の質問に関連していると思います。

まず、ビットのニーモニックをいくつか定義します。

const int FIRST_BIT = 0x1;
const int SECOND_BIT = 0x2;
const int THIRD_BIT = 0x4;

次に、ビット文字列に変換する番号があります。

int x = someValue;

論理&演算子を使用して、ビットが設定されているかどうかを確認できます。

if(x & FIRST_BIT)
{
    // The first bit is set.
}

また、std :: stringを保持し、ビットが設定されている場合はその文字列に1を追加し、ビットが設定されていない場合は0を追加します。文字列の順序に応じて、最後のビットから始めて、最初または最初から最後に移動できます。

これをループにリファクタリングし、各反復後にcurrent_bit_value << = 1を使用して上記のニーモニックビットを計算することにより、任意のサイズの数値に使用できます。

1
Brian R. Bondy

そして、100000 ...、次に010000 ...、0010000 ...などの数値。毎回、結果が0の場合は、char配列に「0」を入力し、そうでない場合は「1」を入力します。

int numberOfBits = sizeof(int) * 8;
char binary[numberOfBits + 1];
int decimal = 29;

for(int i = 0; i < numberOfBits; ++i) {
    if ((decimal & (0x80000000 >> i)) == 0) {
        binary[i] = '0';
    } else {
        binary[i] = '1';
    }
}
binary[numberOfBits] = '\0';
string binaryString(binary);
1
ladookie

直接関数はありません。intのビットに沿って歩き(ヒントは>>を参照)、文字列に「1」または「0」を挿入するだけです。
標準的な面接/宿題タイプの質問のように聞こえます

0
Martin Beckett

これに使用できる小さなヘッダーのみのライブラリがあります ここ

例:

std::cout << ConvertInteger<Uint32>::ToBinaryString(21);
// Displays  "10101"

auto x = ConvertInteger<Int8>::ToBinaryString(21, true);
std::cout << x << "\n"; // displays "00010101"

auto x = ConvertInteger<Uint8>::ToBinaryString(21, true, "0b");
std::cout << x << "\n"; // displays "0b00010101"
0
user427390

直接印刷するsprintfの代わりに、printf関数を使用してフォーマットされた出力を文字列変数に格納します。ただし、これらの関数はC文字列でのみ機能し、C++文字列では機能しないことに注意してください。

0
c4learn.com

リバースなし、追加コピーなし、0パディングありのソリューション:

#include <iostream>
#include <string>

template <short WIDTH>
std::string binary( unsigned x )
{
    std::string buffer( WIDTH, '0' );
    char *p = &buffer[ WIDTH ];

    do {
        --p;
        if (x & 1) *p = '1';
    }
    while (x >>= 1);

    return buffer;
}

int main()
{
    std::cout << "'" << binary<32>(0xf0f0f0f0) << "'" << std::endl;
    return 0;
}
0
risingballs

これは、整数(任意の型)をstd :: stringに変換するための私の最良の実装です。テンプレートを単一の整数型にのみ使用する場合は、テンプレートを削除できます。私の知る限り、C++の安全性とCの不可解な性質の間にはバランスが取れていると思います。必要なヘッダーを必ず含めてください。

_template<typename T>
std::string bstring(T n){
    std::string s;
    for(int m = sizeof(n) * 8;m--;){
            s.Push_back('0'+((n >> m) & 1));
    }
    return s;
}
_

そのように使用してください、

_std::cout << bstring<size_t>(371) << '\n';
_

これは私のコンピューターの出力です(コンピューターごとに異なります)、

_0000000000000000000000000000000000000000000000000000000101110011
_

バイナリ文字列全体がコピーされるため、ビットサイズを表すのに役立つ埋め込みゼロに注意してください。したがって、文字列の長さはビット単位のsize_tのサイズです。

符号付き整数(負の数)を試してみましょう、

_std::cout << bstring<signed int>(-1) << '\n';
_

これは私のコンピューターの出力です(前述のように、コンピューターごとに異なります)、

_11111111111111111111111111111111
_

文字列が小さくなったことに注意してください。これは、signed intsize_tよりも少ないスペースを消費することを証明しています。ご覧のとおり、私のコンピューターは2の補数法を使用して符号付き整数(負の数)を表します。これで、unsigned short(-1) > signed int(1)の理由がわかります。

これは、テンプレートなしでこの関数を作成するために符号付き整数専用に作成されたバージョンです。つまり、符号付き整数を文字列に変換する場合にのみ使用します。

_std::string bstring(int n){
    std::string s;
    for(int m = sizeof(n) * 8;m--;){
            s.Push_back('0'+((n >> m) & 1));
    }
    return s;
}
_
0
antonyjr