【问题标题】:C++ convert binary to decimal for bit values greater than 64 bits对于大于 64 位的位值,C++ 将二进制转换为十进制
【发布时间】:2013-04-05 22:40:25
【问题描述】:

我正在使用此代码将二进制转换为十进制。但是此代码不适用于更多 64 位,因为 __int64 仅包含 8 个字节。您能否告诉建议一种用于将超过 64 位转换为十进制值的算法。我的最终结果也必须是字符串。帮助表示赞赏。谢谢。

 int bin2dec(char *bin)
 {
    __int64  b, k, m, n;
    __int64  len, sum = 0;

    len = strlen(bin) - 1;
    for(k = 0; k <= len; k++)
    {
            n = (bin[k] - '0'); // char to numeric value
            if ((n > 1) || (n < 0))
            {
                    puts("\n\n ERROR! BINARY has only 1 and 0!\n");
                    return (0);
            }
            for(b = 1, m = len; m > k; m--)
            {
                    // 1 2 4 8 16 32 64 ... place-values, reversed here
                    b *= 2;
            }
            // sum it up
            sum = sum + n * b;
    }
    return(sum);
 }

【问题讨论】:

  • 你可以使用 bignum 库。
  • 一个算法?算法肯定是一样的!
  • 您的代码不会将二进制转换为十进制,而是将二进制 ascii 转换为 int64。任何地方都不涉及小数(ascii 或其他)。这表明您根本不想要二进制到十进制,您想要二进制到其他包含超过 64 位的数据类型。
  • 为什么需要算法?您需要的是一种可以容纳超过 64 位的数据类型。

标签: c++


【解决方案1】:

通常,当处理大于一个整数单元可以存储的数据时,解决方案是以下两种情况之一:

  1. 使用字符数组/字符串将值存储为“ASCII”(每个字符一位)
  2. 在数组中使用多个整数来存储值,每个元素使用X 位。

转换并没有什么特别的不同,只是一旦你完成了X 位,你就会转移到下一个元素。

顺便说一句:

int bin2dec(char *bin)
 {
    int  k, n;
    int len;
    __int64  sum = 0;

    len = strlen(bin);
    for(k = 0; k < len; k++)
    {
            n = (bin[k] - '0'); // char to numeric value
            if ((n > 1) || (n < 0))
            {
                    puts("\n\n ERROR! BINARY has only 1 and 0!\n");
                    return (0);
            }
            // sum it up
            sum <<= 1;
            sub += n;
    }
    return(sum);
 }

有点简单。

【讨论】:

    【解决方案2】:

    算法很简单:不断除以 10 的幂,以获得每 10 位的值。诀窍是能够存储大于 64 位的数字并除以 10 的幂。存在存储大数字的算法,您应该找到一个,虽然它们不难纠正,但它们比在 Stackoverflow 上输入答案时要大。

    但基本上,您创建一个累加器 bignum,将其设置为 1 并开始将其乘以 10,直到它的值大于您的目标 bignum。然后你将它除以 10 并启动算法:

    while accum >= 1
    divide source/accum place the dividend in your output string. 
    substract that number time accum from your source.
    divide accum by 10 and loop
    

    你认识那个算法吗?这可能是你在小学时被教导做长除法的方式。嗯,这就是你“打印”十进制二进制数的方式。

    有很多方法可以提高它的性能。 (提示,您不必以 10 为基数工作。对于 32 位整数,以 10^8 为基数,对于 64 位整数,以 10^17 为基数。)但首先您需要一个可以减、加、倍数的库, 除并比较 bignums。

    当然,一个 bignum 库可能已经有一个 toString 函数。

    【讨论】:

      【解决方案3】:

      您可以轻松地将大数字(以任何基数)存储为数字的std::deque——使用双端队列可以轻松地在任一端添加数字。您可以对它们进行基本的算术运算,这使得使用标准的乘法和数字相加算法可以轻松地将二进制转换为十进制:

      std::deque<char> &operator *=(std::deque<char> &a, unsigned b)
      {
          unsigned carry = 0;
          for (auto d = a.rbegin(); d != a.rend(); d++) {
              carry += (*d - '0') * b;
              *d = (carry % 10) + '0';
              carry /= 10; }
          while (carry > 0) {
              a.push_front((carry % 10) + '0');
              carry /= 10; }
          return a;
      }
      
      std::deque<char> &operator +=(std::deque<char> &a, unsigned b)
      {
          for (auto d = a.rbegin(); b > 0 && d != a.rend(); d++) {
              b += (*d - '0');
              *d = (b % 10) + '0';
              b /= 10; }
          while (b > 0) {
              a.push_front((b % 10) + '0');
              b /= 10; }
          return a;
      }
      
      std::string bin2dec(char *bin) {
          std::deque<char> tmp{'0'};
          while (*bin) {
              if (*bin != '0' && *bin != '1') {
                  puts("\n\n ERROR! BINARY has only 1 and 0!\n");
                  return ""; }
              tmp *= 2;
              if (*bin++ == '1')
                  tmp += 1; }
          return std::string(tmp.begin(), tmp.end());
      }
      

      【讨论】:

        【解决方案4】:

        手动:

        int binaryToDec(char *bin)
         {
            int  k, n;
            int len=strlen(bin);
            int  dec = 0;
        
            for(k = 0; k < len; k++)
            {
                    n = (bin[k] - '0');
                    dec <<= 1;
                    dec += n;
            }
            return(dec);
         }
        

        您也可以考虑使用 bitset:

        std::bitset<64> input(*bin);
        std::cout<<input.u_long();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-06
          • 2017-08-08
          • 2013-12-26
          • 2019-01-23
          • 1970-01-01
          • 2018-06-24
          • 1970-01-01
          相关资源
          最近更新 更多