【问题标题】:How to convert very large binary to decimal in C如何在C中将非常大的二进制转换为十进制
【发布时间】:2018-03-15 14:13:23
【问题描述】:

我正在使用 netBean 编写 C 代码,我的任务是将一个非常大的二进制数转换为十进制(二进制数可能高达 100 位),我很困惑,因为我的程序在二进制数约为 50 时工作-60 位,但当输入较大时,它会在运行时自动崩溃。我正在使用 long long int 来存储十进制结果,但它似乎不起作用! 这是我的代码:

 long long int decimal = 0;
    int position = 0;
    for(int i = strlen(binaryInput)-1; i>=0; --i){
        if(binaryInput[i]=='1'){
            decimal += (long long int)(pow(2,position));
        }
        ++position;
    }
    printf("\nDecimal number is: %lli ", decimal);

'binaryInput' 是我从键盘存储 binaryNumber 的字符串。

【问题讨论】:

  • long long int 类型至少为 64 位。并签字。那么,如果它只有 64 位(现代 PC 系统的标准),你怎么能在其中容纳多达 100 位的数据呢?
  • 为什么不使用移位运算符?会比反复使用pow快很多
  • pow() 在这里是个坏主意,它对浮点数进行操作。请改用简单的位移。然后,在典型的 C 实现中没有可以容纳 100 位(二进制数字!)的整数类型。您可以尝试使用非标准的 int128_t 类型。您可能应该改用一组无符号类型。将其转换为十进制表示法,看看例如在double dabble algorithm
  • 你能把数字显示为十六进制吗?如果是这样,您可以翻译任意数量的二进制数字。一次只取 4 位并将它们转换为十六进制。
  • 首先,您需要选择一个能够保持所需结果的内部表示。这意味着一些非常 big 的 int 类型,大小至少为 100 位(long long 没有填满)。或者可能是一个 ASCII 表示形式的数组 char-s...?

标签: c binary decimal


【解决方案1】:

这里有一个提示:

最简单的解决方案是实际取长二进制数,并将其分成两半(或四分之一,或其他)。

跟踪哪些是二进制数的上限,哪些是二进制数的下限。

计算下限和上限的真实值是多少。之后将它们加在一起。

【讨论】:

    【解决方案2】:

    long long int 的范围为 -9,223,372,036,854,775,807 到 9,223,372,036,854,775,807,如 here 所述。 100 位是不可能放在那里的。但是,这种类型是有符号的,您可以尝试使用无符号的,但我没有看到任何关于您的数字是非负数的假设。

    您可以尝试使用适合 128 位签名的 int128_t,但这不是标准 (Why isn't there int128_t?)。

    考虑使用大小为 100 的数组,其中每个单元格将存储一个数字。使用这种方法,建议您使用Double dabble 算法,该算法用于将二进制数转换为二进制编码的十进制 (BCD) 表示法。

    如果您需要一个库,那么 GNU Multiple Precision Arithmetic Library 可以解决问题。

    PS:使用位移而不是pow(),因为它将对浮点值进行操作,并且会降低代码的性能。

    【讨论】:

    • 使用数组的最大问题是打印。在没有特殊算法支持的情况下,如何以十进制打印跨越多个数组元素的内容? 'c' 中应该有一些 bignum 库可以提供它。
    • @Serge 在这个问题上看到我的 cmets -- 使用双涉算法的一些变体。
    • @Serge 我用 Felix 的洞察力和我过去使用过的库更新了我的答案。
    【解决方案3】:

    不确定这是否是最优化的技术。这可以计算多达 1000 位。您可以增加数组分配以计算更长的二进制数 我使用字符串作为输入,使用高中数学技术进行加法和计算 2 的幂

    #include <bits/stdc++.h>
    typedef long long int lli;
    using namespace std;
    
    int main() {
    
        char bin_number[1010];
        //variable for big integer operation 
        int int_number[1010], t_int_number[500];
        /*
         * int_number : converted decimal number will be stored here
         * t_int_number : will be used to calculate the power of 2
         */
    
    
        int bin_length, t_int_length, int_length, index;
        /*
         * bin_length   : length(bin_number)
         * t_int_length : length(t_int_length)
         * int_length   : length(int_length)
         */
    
        bool carry;
    
        while(scanf("%s", bin_number) != EOF) {                     //input binary number
            for (int i = 0; i < 500; i++) {                         //intialize decimal number to 0 and t_int_number to 0
                int_number[i] = 0;
                t_int_number[i] = 0;
            }
    
            //set t_int_number to 1 
            t_int_number[0] = 1;
            t_int_length = 1;
            //set the int_number to 0
            int_length = 1;
            index = 0;
            //calculate input length
            bin_length = strlen(bin_number);
    
            for (int i = bin_length - 1; i >= 0; i--) {                  //checks each digit of binary number
                //if the digit in binary representation is 1
                if (bin_number[i] == '1') {   
                    //sum (int_number, t_int_number)
                    for (int index = 0; index < t_int_length; index++) {
                        int_number[index] +=
                            t_int_number[index];                //sum t_int_number digits
                        if (int_number[index] > 9) {                //if carry
                            int_number[index + 1] ++;
                            int_number[index] -= 10;
                        }
                    }
                    int_length = index;
                    if (int_number[index] != 0) {               //i f length increase for addition 
                        int_length ++;
                    }
                }
    
                //Being ready for next iteration
                //multiplying everytime with 2 and save it to t_int_number
                carry = false;
                for (index = 0; index < t_int_length; index++) {
                    t_int_number[index] += t_int_number[index];     //double the number
                }
                for (index = 0; index < t_int_length; index++) {
                    if (t_int_number[index] > 9) {
                        t_int_number[index] -= 10;
                        t_int_number[index + 1]++;
                    }
                }
                if (t_int_number[index] != 0) {
                    t_int_length++;
                }
            }
    
            //printing the decimal number
            for (int i = int_length - 1; i >=0; i--) {
                printf("%d", int_number[i]);
            }
            printf("\n");
        }
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2017-02-25
      • 2011-07-19
      • 2012-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-02
      • 2019-08-29
      相关资源
      最近更新 更多