web-dev-qa-db-ja.com

整数のバイナリ文字列への変更

私は現在、compアーキテクチャクラスのC++でのMIPSプロセッサのシミュレーションに取り組んでおり、10進数から2進数への変換(符号付きの数値の両方の方法)でいくつかの問題があります。私の現在のアルゴリズムは、1 << = 31のintの範囲外の領域に入るため、最後のビットまではすべて正常に機能しています。起動して実行するには、正しい方向にナッジが必要です。ありがとう!

//Assume 32 bit decimal number
string DecimalToBinaryString(int a)
{
    string binary = "";
    int mask = 1;
    for(int i = 0; i < 31; i++)
    {
        if((mask&a) >= 1)
            binary = "1"+binary;
        else
            binary = "0"+binary;
        mask<<=1;
    }
    cout<<binary<<endl;
    return binary;
}

完全を期すために、他のアルゴリズムも含めています。コメントがないことをおaびしますが、かなり簡単です。

int BinaryStringToDecimal(string a)
{
    int num = 0;
    bool neg = false;
    if(a.at(0) == '1')
    {
        neg = true;
        for(int x = a.length()-1; x >= 0; x--)
        {
            if(a.at(x) == '1')
                a.at(x) = '0';
            else a.at(x) = '1';
        }
        a.at(a.length()-1) += 1;
        for(int x = a.length()-1; x >= 0; x--)
        {
            if(a.at(x) == '2')
            {
                if(x-1 >= 0)
                {
                    if(a.at(x-1) == '1')
                        a.at(x-1) = '2';
                    if(a.at(x-1) == '0')
                        a.at(x-1) = '1';
                    a.at(x) = '0';
                }
            }
            else if(a.at(x) == '3')
            {
                if(x-1 >= 0)
                    a.at(x-1) += '2';
                a.at(x) = '1';
            }
        }
        if(a.at(0) == '2')
            a.at(0) = '0';
        else if(a.at(0) == '3')
            a.at(0) = '1';
    }
    for(int x = a.length()-1; x >= 0; x--)
    {
        if(a.at(x) == '1')
            num += pow(2.0, a.length()-x-1);
    }
    if(neg)
        num = num*-1;   
    return num;
 }

また、誰かがこれらをより効率的に書くための良い方法を知っているなら、それを聞きたいです。プログラミングの入門クラスは2つしかありませんでしたが、それぞれのスタイルがどれほど気に入っているかを確認するために、さまざまなテクニックを試してきました。

19
Paul Ruiz

これらには実際に標準的なワンライナーがあります。

#include <bitset>

std::string s = std::bitset< 64 >( 12345 ).to_string(); // string conversion

std::cout << std::bitset< 64 >( 54321 ) << ' '; // direct output

std::bitset< 64 > input;
std::cin >> input;
unsigned long ul = input.to_ulong();

デモとしてこの実行を参照

57
Potatoswatter

交換:

if((mask&a) >= 1)

どちらかと:

if ((mask & a) != 0)

または:

if (mask & a)

問題は、最後のビットが正の数ではなく負の数を与えることです。

4

1 << = 31の問題は、他のコメントで対処されています。文字列-> int変換のコード部分に関して、いくつかのオプションがあります:

  • 文字列をストリームに変換し、ストリームに定義されたoperator >>(int&)を使用します// Correction-> :-) setbase()ストリーム修飾子が引数として2つの値をサポートしないことを気にしないでください
  • ベース値引数(バイナリの場合は2)を持つ標準C関数strtol()を使用します
  • または、変換を自分で実装したい場合は、次のコードを試してください。

    int BinaryStringToDecimal(string a) 
    {
        int Rslt = 0;
        int Mask = 1;
        for (int i = a.length()-1; i >= 0; --i, Mask <<= 1) {
            if (a.at(i) != '0') {
                Rslt |= Mask;
            }
        }
        return (Rslt);
    }
    

このコードは、コードと比較すると負の数を異なる方法で処理することに注意してください。関数では、最上位ビットが符号として扱われます。関数の文字列引数の左端のビットが位置32にない場合(右からカウントする場合)、関数は誤った結果を生成する可能性があります。ここで提案されているコードでは、特別なシグナム処理はありません。しかし、「1」を左端に持つ32桁の文字列を取得すると、intのMSBの結果は== 1になり、整数は負の値になります(そうあるべきです)

0
Pavel Zhuravlev

コードを確認しましたが、エラーは見つかりませんでした。ここに私が使用したコードがあります...

#include <iostream>
#include <string>
using namespace std;

int main ()
{
  int a=1111165117;
  string binary  ("");
    int mask = 1;
    for(int i = 0; i < 31; i++)
    {
    if((mask&a) >= 1)
        binary = "1"+binary;
    else
        binary = "0"+binary;
     mask<<=1;
 }
 cout<<binary<<endl;
 system("PAUSE");         //optional if not using ideone
 return EXIT_SUCCESS;     //optional if not using ideone
 }

出力は1001110001010110101111010011101になります。これを ideone で実行できます。

0
Ravi Kumar

そして、なぜintuintにキャストできないのですか?符号ビットを気にする必要がないため、バイナリ文字列を生成するのは非常に簡単です。バイナリ文字列をintに変換する場合も同様です:uintとしてビルドし、intにキャストします:

string DecimalToBinaryString(int a)
{
    uint b = (uint)a;
    string binary = "";
    uint mask = 0x80000000u;
    while (mask > 0)
    {
        binary += ((b & mask) == 0) ? '0' : '1';
        mask >>= 1;
    }
    cout<<binary<<endl;
    return binary;
}

そして、もちろん、文字列バッファーの事前割り当てなど、前述の最適化を適用できます。

他の方法で行く:

uint b = 0;
for (int i = 31; i >=0; --i)
{
    b <<= 1;
    if (a.at(i) == '1')
        b |= 1;
}
int num = (int)b;
0
Jim Mischel