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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:12:31  来源:igfitidea点击:

Changing integer to binary string of digits

c++algorithmbinary

提问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();

See this run as a demo.

将此运行视为演示

回答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 intto 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;