C++ 将整数更改为二进制数字串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8222127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing integer to binary string of digits
提问by Paul Ruiz
I'm currently working on a simulation of the MIPS processor in C++ for a comp architecture class and having some problems converting from decimal numbers to binary (signed numbers both ways). Everything's working fine until the very last bit because my current algorithm falls into out of bounds areas for int on 1<<=31. Just need a nudge in the right direction to get it up and running. Thanks!
我目前正在用 C++ 为 comp 架构类模拟 MIPS 处理器,并且在从十进制数转换为二进制数(双向有符号数)时遇到了一些问题。一切正常,直到最后一点,因为我当前的算法在 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;
}
I'm also including my other algorithm for completeness. I apologize for the lack of comments, but it's fairly straight forward.
为了完整性,我还包括了我的其他算法。我为缺乏评论而道歉,但这是相当直接的。
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;
}
Also if anyone knows any good ways to go about writing these more efficiently I'd love to hear it. I've only had the two introductory programming classes but have been playing with different techniques to see how well I like their style.
另外,如果有人知道更有效地编写这些的任何好方法,我很乐意听到它。我只上过两门介绍性编程课程,但一直在尝试不同的技术,以了解我对他们风格的喜爱程度。
回答by Potatoswatter
There are actually standard one-liners for these.
这些实际上有标准的单衬。
#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();
回答by Jonathan Leffler
Replace:
代替:
if((mask&a) >= 1)
with either:
与:
if ((mask & a) != 0)
or:
或者:
if (mask & a)
Your problem is that the last bit gives you a negative number, not a positive one.
你的问题是最后一位给你一个负数,而不是一个正数。
回答by Ravi Kumar
I checked your code and couldn't find any error. Here is the code that i used...
我检查了你的代码,没有发现任何错误。这是我使用的代码...
#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
}
Output will be 1001110001010110101111010011101. I you can run this on ideone
输出将是 1001110001010110101111010011101。我你可以在ideone上运行它
回答by Pavel Zhuravlev
The problem with 1<<=31 has been addressed in other comment. Concerning the code piece for string -> int conversion, you have several options:
1<<=31 的问题已在其他评论中解决。关于 string -> int 转换的代码段,您有几种选择:
- convert string to stream and use operator>>(int&) defined for stream //Correction - never mind that >:-) setbase() stream modifier does not support 2 value as argument
- use standard C function strtol() which has base value argument (2 for binary)
or if you really want to implement the conversion yourself try the following code:
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); }
- 将字符串转换为流并使用为流定义的 operator>>(int&) //更正 - 没关系>:-) setbase() 流修饰符不支持 2 值作为参数
- 使用标准 C 函数 strtol() ,它具有基值参数(二进制为 2)
或者,如果您真的想自己实现转换,请尝试以下代码:
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); }
Note that this code deals with negative numbers differently when compared with your code: in your function highest order bit is taken as signum. If the leftmost bit in string argument for your function is not in position 32 (when counting from right) your function may produce incorrect results. In the code suggested here there is no special signum treatment. But if you get the string of 32 digits with '1' as leftmost of them the MSB in int result will be == 1 and the integer will be negative (as it should be)
请注意,与您的代码相比,此代码处理负数的方式有所不同:在您的函数中,最高位被视为符号。如果您的函数的字符串参数中最左边的位不在位置 32(从右数起),您的函数可能会产生不正确的结果。在此处建议的代码中,没有特殊的符号处理。但是,如果您得到 32 位数字的字符串,其中最左边的是 '1',则 int 结果中的 MSB 将为 == 1,整数将为负数(应该是)
回答by Jim Mischel
And why can't you just cast the int
to a uint
? Then it's very easy to generate the binary string because you don't have to worry about the sign bit. Same goes for converting a binary string to an int
: build it as a uint
, and then cast it to int
:
为什么你不能将 the 转换int
为 a uint
?然后就很容易生成二进制字符串了,因为你不必担心符号位。将二进制字符串转换为int
: 将其构建为 a 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;
}
And, of course, you can apply the mentioned optimizations, like pre-allocating the string buffer, etc.
而且,当然,您可以应用上述优化,例如预先分配字符串缓冲区等。
Going the other way:
走另一条路:
uint b = 0;
for (int i = 31; i >=0; --i)
{
b <<= 1;
if (a.at(i) == '1')
b |= 1;
}
int num = (int)b;