为什么在我的二进制到十进制转换器程序中只有前 2 个输出是正确的?

Why are only the first 2 outputs correct in my binary to decimal converter programm?

我必须编写一个转换器,它从 numbers[] 获取字符串并将它们输出为小数。

我正在遍历大小和索引,然后将当前索引与其位置的幂相加,然后将其相加。比如:101 = 1^2 + 0^1 + 1^0

所以我目前坚持这个:

#include <stdio.h>

#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm

int main() {
    char* numbers[] = {
        "01001001",
        "00101010",
        "010100111001",
        "011111110100101010010111",
        "0001010110011010101111101111010101110110",
        "01011100110000001101"};
    
    // Add here..

int strlen(char *str){
int len=0;
for(;str[len]!='[=10=]';len++){}
return len;
}

int sum = 0;
int length = sizeof(numbers) / sizeof(numbers[0]);

for( int i = 0; i < length; i++ ){
    
     int size = strlen(numbers[i]);
     
    for (int j = 0; j < size; j++) {
     
        if(numbers[i][j] == '1'){ 
            sum += 1 * pow(2,j-1);
        }else{
            sum += 0 * pow(2,j-1);
        }
    }
       printf("%s to the base of 2 \nequals %d  to the base of 10 \n\n",numbers[i], sum); 
       sum = 0;
       
    }
            
    return 0;
}

前两个循环的输出是正确的,即01001001 = 73和00101010 = 42。但是,一旦长度变大,我的输出就完全错误了;例如010100111001 = 1253 而不是 1337 和 011111110100101010010111 = 7645567 而不是 8342167.

sizeof(); // it will give you the size of datatype (in bytes), not the length of a string.

您必须改用字符串函数。

length = strlen(numbers[0]);

你的功能很糟糕,很复杂,而且使用 pow。您不需要知道字符串的长度。

可以做得更简单:

unsigned long long bstrtoint(const char *str)
{
    unsigned long long result = 0;

    while(*str)
    {
        result *= 2;
        result += *str++ == '1';
    }
    return result;
}

或对于任何基数(少于位数)

//bad digits considered as zeroes
static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUWXYZ";
unsigned long long strtoint(const char *str, unsigned base)
{
    unsigned long long result = 0;
    char *ppos;

    while(*str)
    {
        result *= base;
        result += (ppos = strchr(digits, toupper(*str++))) ? (ppos - digits < base) ? ppos - digits : 0 : 0;
    }
    return result;
}

示例:

    printf("%llu\n", bstrtoint("1111000011110000"));
    printf("%llu\n", strtoint("0001010110011010101111101111010101110110", 2));
    printf("%llu\n", strtoint("1dr45Xvy4", 36)); // base 36 number

https://godbolt.org/z/bsG5rfTsb

如果您想使用您的程序布局并正确执行:

int main(void) // For strict compliance, you should add the "void" argument list
{
    char* numbers[] = {
        "01001001",
        "00101010",
        "010100111001",
        "011111110100101010010111",
        "0001010110011010101111101111010101110110",
        "01011100110000001101" };

    unsigned long long sum = 0;
    size_t length = sizeof(numbers) / sizeof(numbers[0]);

    for (size_t i = 0; i < length; i++) 
    {
        size_t size = strlen(numbers[i]); // strlen gives a "size_t" type
        sum = 0;
        for (size_t j = 0; j < size; j++) 
        { 
            sum *= 2;
            if (numbers[i][j] == '1') 
            {
                sum += 1;
            }
        }
        printf("%s to the base of 2 \nequals %llu  to the base of 10 \n\n", numbers[i], sum);
    }
    return 0;
}

但您不必将字符串整合两次 - strlen 根本不需要

int main(void) // For strict compliance, you should add the "void" argument list
{
    char* numbers[] = {
        "01001001",
        "00101010",
        "010100111001",
        "011111110100101010010111",
        "0001010110011010101111101111010101110110",
        "01011100110000001101" };

    unsigned long long sum = 0;
    size_t length = sizeof(numbers) / sizeof(numbers[0]);

    for (size_t i = 0; i < length; i++) 
    {
        sum = 0;
        for (size_t j = 0; numbers[i][j] != 0; j++) 
        { 
            sum *= 2;
            if (numbers[i][j] == '1') 
            {
                sum += 1;
            }
        }
        printf("%s to the base of 2 \nequals %llu  to the base of 10 \n\n", numbers[i], sum);
    }
    return 0;
}

您的代码存在许多问题。首先,正如评论中指出的那样,您正在从左到右处理二进制数字,而您应该从右到左处理。

其次,在另一个函数中声明一个函数(就像您为 strlen 所做的那样)不是标准 C(尽管某些编译器可能允许这样做)。如果你真的不能使用标准的 strlen 函数(在 <string.h> 中提供),那么将你的定义移到 main.

的主体之外(和之前)

第三,您不应该使用 pow 函数(它接受 returns double 值)进行整数运算。只需使用一个 运行 int 变量,并在每次内部 for 循环运行时将其乘以二。

第四,您的 "0001010110011010101111101111010101110110" 值将溢出大多数机器上的 int 类型(假设是 32 位),因此请尝试在必要时使用 long long int(最有可能是 64 位) .

最后,无论 x 是什么,都没有必要将 0 * x 添加到任何内容,因此您可以取消 else 块。

这是一个工作版本(使用标准 strlen):

#include <stdio.h>
#include <string.h> // For "strlen" - we don't need math.h if we don't use "pow".

int main(void) // For strict compliance, you should add the "void" argument list
{
    char* numbers[] = {
        "01001001",
        "00101010",
        "010100111001",
        "011111110100101010010111",
        "0001010110011010101111101111010101110110",
        "01011100110000001101" };

    long long int sum = 0; // So we can use more than 32 bits!
    size_t length = sizeof(numbers) / sizeof(numbers[0]);
    for (size_t i = 0; i < length; i++) {
        int size = (int)strlen(numbers[i]); // strlen gives a "size_t" type
        long long int p = 1;
        for (int j = size-1; j >= 0; j--) { // Start at the END of the string and work backwards!
            if (numbers[i][j] == '1') {
                sum += p;
            }
            // No point in adding zero times anything!
            p *= 2; // Times by two each time through the loop
        }
        printf("%s to the base of 2 \nequals %lld  to the base of 10 \n\n", numbers[i], sum);
        sum = 0;

    }
    return 0;
}