C中二进制转十进制出错

Converting binary to decimal goes wrong in C

我编写了这个程序,将二进制数传递给函数并打印该二进制数的十进制值。问题是,如果二进制数变大(比如 11 个数字),该函数会打印出完全不同的内容。我试着解决了几个小时,但没有任何效果。

所以我的问题是:我怎样才能改变我的程序,以便它打印正确的十进制数,即使二进制数变大了?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdint.h>

int int_log2_64(uint64_t x) { return 63 ^ __builtin_clzll(x); }
#define K(T) (((sizeof(#T) - 1) << 32) - T)
int digit_count(uint32_t x)
{

    static uint64_t table[] = {
        K(0), K(0), K(0),
        K(10), K(10), K(10),                         // 64
        K(100), K(100), K(100),                      // 512
        K(1000), K(1000), K(1000),                   // 4096
        K(10000), K(10000), K(10000),                // 32k
        K(100000), K(100000), K(100000),             // 256k
        K(1000000), K(1000000), K(1000000),          // 2048k
        K(10000000), K(10000000), K(10000000),       // 16M
        K(100000000), K(100000000), K(100000000),    // 128M
        K(1000000000), K(1000000000), K(1000000000), // 1024M
        K(1000000000), K(1000000000)                 // 4B
    };

    int lg2 = int_log2_64(x);

    uint64_t n = (uint64_t)(x) + table[lg2];

    return n >> 32;
}

void binaryToDecimal(long long int bin)
{
    int l = digit_count(bin);
    char str[l];
    itoa(bin, str, 10);
    float sum[l];
    int x = l - 1;
    float answer;

    for (int i = 0; i < l; i++)
    {
        if (str[i] == '1')
        {
            sum[i] = pow(2, x);
        }
        x--;
    }

    for (int i = 0; i < l; i++)
    {
        answer = answer + sum[i];
    }
    printf("%.0f", answer);
}

int main()
{
    long long int bin = 10101101101;
    binaryToDecimal(bin);
}

P.S。我更改为此代码并且有效

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

void binaryToDecimal(char *bin)
{
    int l = strlen(bin);
    int x = l - 1;
    float sum[l];
    float answer = 0;

    for (int i = 0; i < l; i++)
    {
        if (bin[i] == '1')
            answer += pow(2, x);
        else
            sum[i] = 0;
        x--;
    }

    printf("%.0f", answer);
}

int main()
{
    binaryToDecimal("010101101101");
}

您的代码过于复杂。切勿使用浮点数进行整数计算。

unsigned binaryToDecimal(long long int bin)
{
    unsigned answer = 0;
    int shift = 0;
    while(bin)
    {
        answer += (bin % 10) << shift++;
        bin /= 10;
    }
    return answer;
}

int main()
{
    long long int bin = 10101101101;
    printf("%u\n", binaryToDecimal(bin));
}

https://godbolt.org/z/5E8Gv6oqf

或者用字符串传递二进制数:

unsigned binaryToDecimal(char *str)
{
    unsigned answer = 0;
    while(*str)
    {
        answer <<= 1;
        answer += *str++ == '1';
    }
    return answer;
}

int main()
{ 
    printf("%u\n", binaryToDecimal("10101101101"));
}

https://godbolt.org/z/4vfnETY1f

How can I change my program so that it prints the right decimal number even when the binary number gets big?

通过使您的 bin 变量成为 字符串

也就是你要

void binaryToDecimal(const char *str)
{
   ...
}

然后你可以调用

binaryToDecimal("101111000110000101001110");

在进行基数转换时,我认为使用整型变量作为输入总是错误的。如果我说

int x = 12;

x 是一个十进制整数”不是 正确的。 x 是一个整数,句号——我只是碰巧用了一个十进制常量来得到一个值。或者如果我说

int y = 0x7b;

那么说 y 是十六进制是没有意义的——同样,y 只是一个整数。

表示整数的基数仅重要:

  • 在输入时,当我们使用 scanf%d%o%x 格式从用户那里读取数字时
  • 使用标准库 atoistrtol 函数转换字符串时
  • 输出时,当我们使用 printf%d%o%x 格式打印数字时

但在所有这些情况下,基数重要的表示是一串数字字符,而不是整数。

不编写接受整数的“二进制到...”函数有两个原因。一是,如您所见,它人为地且不必要地限制了您可以转换的数字的范围。但更大的原因是这让您的读者感到困惑,因为它 错误 。如果我看到函数调用

f(1001)

我心里想,“好吧,常数值一千零一正在传递给函数 f。”在任何情况下我都不会想象它实际上是在尝试传递二进制数 9。