私は現在、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つしかありませんでしたが、それぞれのスタイルがどれほど気に入っているかを確認するために、さまざまなテクニックを試してきました。
これらには実際に標準的なワンライナーがあります。
#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();
交換:
if((mask&a) >= 1)
どちらかと:
if ((mask & a) != 0)
または:
if (mask & a)
問題は、最後のビットが正の数ではなく負の数を与えることです。
1 << = 31の問題は、他のコメントで対処されています。文字列-> int変換のコード部分に関して、いくつかのオプションがあります:
または、変換を自分で実装したい場合は、次のコードを試してください。
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になり、整数は負の値になります(そうあるべきです)
コードを確認しましたが、エラーは見つかりませんでした。ここに私が使用したコードがあります...
#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 で実行できます。
そして、なぜint
をuint
にキャストできないのですか?符号ビットを気にする必要がないため、バイナリ文字列を生成するのは非常に簡単です。バイナリ文字列を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;