3

我有一个简单的代码来将二进制数转换为十进制数。在我的编译器中,对于小于 1000 的数字,分解工作得很好,超过输出总是相同的 1023。有人知道吗?

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

// how many power of ten is there in a number 
// (I don't use the pow() function to avoid trouble with floating numbers)
int residu(int N)
{
    int i=0;
    while(N>=1){
        N=N/10;
        i++;
    }
    return i;
}

//exponentiating a number a by a number b
int power(int a, int b){
    int i;
    int res=1;
    for (i=0;i<b;i++){res=a*res;}
    return res;
}

//converting a number N
int main()
{
    int i;

    //the number to convert
    int N;
    scanf("%d",&N);

    //the final decimal result
    int res=0;
    //we decompose N by descending powers of 10, and M is the rest
    int M=0;

    for(i=0;i<residu(N);i++){
        // simple loop to look if there is a power of (residu(N)-1-i) in N, 
        // if yes we increment the binary decomposition by 
        // power(2,residu(N)-1-i)
        if(M+ power(10,residu(N)-1-i) <= N)
        {
            M = M+power(10,residu(N)-1-i);
            res=power(2,residu(N)-1-i)+res;
        }
    }
    printf("%d\n",res);
}
4

5 回答 5

9

是的,试试这个:

#include <stdio.h>
int main(void) 
{ 
char bin; int dec = 0;

while (bin != '\n') { 
scanf("%c",&bin); 
if (bin == '1') dec = dec * 2 + 1; 
else if (bin == '0') dec *= 2; } 

printf("%d\n", dec); 

return 0;

}
于 2012-09-09T12:15:13.977 回答
3

这很可能是因为您使用的int是存储二进制数。Anint不会存储 2^31 以上的数字,即 10 位长,而 1023 是 10 位二进制数字所能得到的最大数字。

将输入数字作为字符串读取,然后处理字符串的每个字符会容易得多。

于 2012-09-09T11:19:24.100 回答
1

经过一些实验,我认为您的程序旨在仅接受由 1 和 0 组成的数字作为基数为 10 的数字(%d读取十进制数)。例如,给定输入10,它输出2;给定1010,它输出10;给定10111001,它输出185

到目前为止,一切都很好。不幸的是,给定1234,它输出15,这有点出乎意料。

如果您在一台int32 位有符号值的机器上运行,那么您不能输入超过 10 位的数字,因为您超出了 32 位的限制int(可以处理 ±20 亿,条款)。该scanf()函数不能很好地处理溢出。

您可以通过回应您的输入来帮助自己;这是一种标准的调试技术。确保计算机获得了您期望的值。

我不会尝试修复代码,因为我认为您正在以完全错误的方式解决问题。(我什至不确定是否最好将其描述为二进制到十进制,或十进制到二进制,或十进制到二进制到十进制!)您最好将输入读取为(最多 31 个)字符的字符串,然后验证每个都是 0 或 1。假设这是正确的,那么您可以非常直接地处理字符串以生成一个可以格式化printf()为小数的值。

于 2012-09-09T11:42:35.443 回答
0
#include <stdio.h>  //printf
#include <string.h> //strlen
#include <stdint.h> //uintX_t or use int instead - depend on platform.

/* reverse string */
char *strrev(char *str){
    int end = strlen(str)-1;
    int start = 0;

    while( start<end ){
        str[start] ^= str[end];
        str[end]   ^= str[start];
        str[start] ^= str[end];
        ++start;
        --end;
    }
    return str;
}


/* transform binary string to integer */
uint32_t binstr2int(char *bs){
    uint32_t ret = 0;
    uint32_t val = 1;

    while(*bs){
       if (*bs++ == '1') ret = ret + val;
       val = val*2;
    }
    return ret;
}

int main(void){
    char binstr[] = "1010101001010101110100010011111"; //1428875423
    printf("Binary: %s, Int: %d\n", binstr, binstr2int(strrev(binstr)));
    return 0;
}
于 2013-11-13T13:33:33.293 回答
0

左移与乘以 2 相同,效率更高,所以我认为这是一个更像 c 的答案:

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

int bin2int(const char *bin) 
{
    int i, j;
    j = sizeof(int)*8;
    while ( (j--) && ((*bin=='0') || (*bin=='1')) ) {
        i <<= 1;
        if ( *bin=='1' ) i++;
        bin++;
    }
    return i;
}

int main(void) 
{ 
    char* input = NULL;
    size_t size = 0;

    while ( getline(&input, &size, stdin) > 0 ) {
        printf("%i\n", bin2int(input)); 
    }
    free(input);
}
于 2012-09-09T15:56:39.427 回答