【问题标题】:Converting to binary in C++在 C++ 中转换为二进制
【发布时间】:2011-02-28 16:05:20
【问题描述】:

我做了一个将数字转换为二进制的函数。由于某种原因,它不起作用。它给出了错误的输出。输出是二进制格式,但对于以零结尾的二进制数,它总是给出错误的结果(至少这是我注意到的......)

unsigned long long to_binary(unsigned long long x)
{
    int rem;
    unsigned long long converted = 0;

    while (x > 1)
    {
        rem = x % 2;
        x /= 2;
        converted += rem;
        converted *= 10;
    }

    converted += x;

    return converted;
}

请帮我解决它,这真的很令人沮丧..

谢谢!

【问题讨论】:

  • 这真的很令人沮丧,因为数字已经是二进制形式了,不需要转换。你可以做的是打印它的部分,但互联网上有大量的例子。
  • 您正在做的是将十进制数转换为看起来像二进制但值错误的十进制数。你的家庭作业到底是什么?
  • 这不是家庭作业。我想在这里学习一些东西。我知道数字已经是二进制的,但它们显示为十进制。我只想将它们显示为二进制,为此我需要将十进制表示转换为二进制。还是我?如果有办法将它们显示为二进制表示,我真的很想看看。谢谢

标签: c++ binary decimal


【解决方案1】:

使用 std::bitset 进行翻译:

#include <iostream>
#include <bitset>
#include <limits.h>

int main()
{
    int     val;
    std::cin >> val;

    std::bitset<sizeof(int) * CHAR_BIT>    bits(val);
    std::cout << bits << "\n";

}

【讨论】:

    【解决方案2】:
    1. 您正在反转位。
    2. 您不能将 x 的剩余部分用作终止循环的指示符。

    考虑例如4.

    第一次循环迭代后:

    rem == 0
    converted == 0
    x == 2
    

    第二次循环迭代后:

    rem == 0
    converted == 0
    x == 1
    

    然后你设置转换为1。

    试试:

    int i = sizeof(x) * 8; // i is now number of bits in x
    while (i>0) {
      --i;
      converted *= 10;
      converted |= (x >> i) & 1;
      // Shift x right to get bit number i in the rightmost position, 
      // then and with 1 to remove any bits left of bit number i,
      // and finally or it into the rightmost position in converted
    }
    

    以 x 作为无符号字符(8 位)运行上述代码,值为 129(二进制 10000001)

    从i = 8 开始,unsigned char * 8 的大小。在第一个循环迭代中,i 将是 7。然后我们将 x (129) 向右移动 7 位,得到值 1。这与 converted 相或,变为 1。下一次迭代,我们首先将 converted 乘以 10(所以现在它是 10),然后我们将 x 向右移动 6 位(值变为 2)并将其与1(值变为 0)。我们将 0 与 converted 进行或运算,然后仍为 10。第 3-7 次迭代做同样的事情,converted 与 10 相乘,并从 x 中提取一个特定位并与 converted 进行或运算。经过这些迭代,converted 为 1000000。

    在最后一次迭代中,首先converted 乘以 10 并变为 10000000,我们将x 右移 0 位,得到原始值 129。我们将 x 与 1 与,得到值 1。然后 1 OR'ed 到 converted,变成 10000001。

    【讨论】:

    • 他没有使用遗体作为停止条件,我认为您的代码需要一些解释。我理解它,但我怀疑具有基本 C 知识的人会。而且你错过了converted的初始化,这很重要。
    • 你能解释一下最后一行吗?您出于什么目的使用按位 OR、AND 和右移?还有,第一行的目的是什么(sizeof(x) * 8)?
    • 在理解这个方面仍然有点困难......请原谅我的无知 :P 你能举个例子来说明它是如何工作的吗?
    • 太棒了!谢谢!我现在明白了!我使用 gprof 进行了分析,这似乎是最好的方法。
    【解决方案3】:

    你做错了;)

    http://www.bellaonline.com/articles/art31011.asp

    第一个除法的剩余部分是二进制形式的最右边位,使用您的函数它成为最左边的位。

    你可以这样做:

    unsigned long long to_binary(unsigned long long x)
    {
        int rem;
        unsigned long long converted = 0;
        unsigned long long multiplicator = 1;
    
        while (x > 0)
        {
            rem = x % 2;
            x /= 2;
            converted += rem * multiplicator;
            multiplicator *= 10;
        }
    
        return converted;
    }
    

    编辑:CygnusX1 提出的代码效率更高,但我认为不够全面,我建议采用他的版本。

    改进:我更改了while循环的停止条件,因此我们可以删除在末尾添加x的行。

    【讨论】:

      【解决方案4】:

      您实际上是在反转二进制数! to_binary(2) 将返回 01,而不是 10。当初始 0 被截断时,它看起来与 1 相同。

      这样做怎么样:

      unsigned long long digit = 1;
      while (x>0) {
        if (x%2)
          converted+=digit;
        x/=2;
        digit*=10;
      }
      

      【讨论】:

        【解决方案5】:
        【解决方案6】:

        如果要将数字显示为二进制,则需要将其格式化为字符串。据我所知,最简单的方法是使用STL bitset。

        #include <bitset>
        #include <iostream>
        #include <sstream>
        
        typedef std::bitset<64> bitset64;
        
        
        std::string to_binary(const unsigned long long int& n)
        {
                const static int mask = 0xffffffff;
                int upper = (n >> 32) & mask;
                int lower = n & mask;
                bitset64 upper_bs(upper);
                bitset64 lower_bs(lower);
                bitset64 result = (upper_bs << 32) | lower_bs;
                std::stringstream ss;
                ss << result;
                return ss.str();
        };
        
        int main()
        {
                for(int i = 0; i < 10; ++i)
                {
                        std::cout << i << ": " << to_binary(i) << "\n";
                };
                return 1;
        };
        

        这个程序的输出是:

        0: 0000000000000000000000000000000000000000000000000000000000000000
        1: 0000000000000000000000000000000000000000000000000000000000000001
        2: 0000000000000000000000000000000000000000000000000000000000000010
        3: 0000000000000000000000000000000000000000000000000000000000000011
        4: 0000000000000000000000000000000000000000000000000000000000000100
        5: 0000000000000000000000000000000000000000000000000000000000000101
        6: 0000000000000000000000000000000000000000000000000000000000000110
        7: 0000000000000000000000000000000000000000000000000000000000000111
        8: 0000000000000000000000000000000000000000000000000000000000001000
        9: 0000000000000000000000000000000000000000000000000000000000001001
        

        【讨论】:

          【解决方案7】:

          如果您的目的只是将它们显示为二进制表示,那么您可以尝试itoa 或std::bitset

          #include <stdlib.h>
          #include <stdio.h>
          #include <iostream>
          #include <bitset>
          
          using namespace std;
          
          int main()
          {
              unsigned long long x = 1234567890;
          
              // c way
              char buffer[sizeof(x) * 8];
              itoa (x, buffer, 2);
              printf ("binary: %s\n",buffer);
          
              // c++ way
              cout << bitset<numeric_limits<unsigned long long>::digits>(x) << endl;
          
              return EXIT_SUCCESS;
          }
          

          【讨论】:

          • itoa 是一个非标准函数,很多平台都没有(我只在windows上见过)。
          【解决方案8】:
          void To(long long num,char *buff,int base)
          {
              if(buff==NULL)      return;
              long long m=0,no=num,i=1;
          
              while((no/=base)>0) i++;
              buff[i]='\0';
          
              no=num;
              while(no>0)
              {
                  m=no%base;
                  no=no/base;
                  buff[--i]=(m>9)?((base==16)?('A' + m - 10):m):m+48;
              }
          }
          

          【讨论】:

            【解决方案9】:

            这是一个简单的解决方案。

            #include <iostream>
            using namespace std;
            int main()
            {
                int num=241; //Assuming 16 bit integer
                for(int i=15; i>=0; i--) cout<<((num >> i) & 1);
                cout<<endl;
                for(int i=0; i<16; i++) cout<<((num >> i) & 1);
                cout<<endl;
                return 0;
            }
            

            【讨论】:

              猜你喜欢
              • 2019-03-18
              • 2012-12-26
              • 2012-06-05
              • 2014-03-24
              • 1970-01-01
              • 2019-03-24
              • 2019-04-26
              • 2021-12-26
              相关资源
              最近更新 更多