将数字从给定基数转换为基数10

时间:2009-09-27 00:50:40

标签: c

我正在尝试从任何基数转换为基数10.对于010111 base 2的输入它给我1,而对于35 base 9它给我18应该是38.任何建议?

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

#define LENGTH 6

double pow( double x, double power );

int main()
{
    char input[LENGTH+1] ;
    int base;
    unsigned decValue ;
    char values[] = "0123456789ABCDEFG";
    int i;

    puts( "Enter a value, and its base: " );
    scanf( "%s", &input );
    scanf( "%i", &base );

    for( i = LENGTH-1 ; i >= 0; i-- )
    {       
        int index = strchr(values, input[ i ] ) - values;

        decValue += index * pow( base , i - LENGTH + 1 );
    }

    printf( "%s (base-%u) equals %u \n", input, base, decValue );


    return 0;
}

6 个答案:

答案 0 :(得分:3)

由于i < LENGTHi - LENGTH + 1为负数,因此pow为0。

所以,你应该使用pow( base , LENGTH - i - 1 ) - 那个人是个大人物。其他大错:你应该使用strlen(输入),无论你在哪里使用LENGTH; 你应该将decValue初始化为0.可能有其他人,我停止照顾前三个(这是加州之后,“三击,你出去”的法律;-)

答案 1 :(得分:3)

最困扰我的是你将浮点运算混合成一个整数问题。它不仅效率较低,而且当结果转换回int时,它可能会被舍入或者愚蠢。假设的例子:

double n = pow(2,3); //becomes 7.99999999999999999999999 for some silly reason
int in = n; //rounds down to 7

虽然在您的情况下甚至可能不会发生这种情况,但要注意整数&lt; - &gt;浮点转换,并在不必要时避免它们。

更好的解决方案是逐步增加功率。如果我是你,我会从数字的开头到结尾重复。伪代码:

let s be the input string's digits;
let r be the radix;
let n be the resulting number;
n=0;
for (i=0; i<s.size(); i++) {
    n *= radix;
    n += s[i];
}

这个概念是你拿起数字并将它们转移到数字中。例如。 123十进制:

1
(shift 1 left, then add 2)
12
(shift 12 left, then add 3)
123

在给定基数的整数上下文中向左移位,只是乘以基数。

答案 2 :(得分:3)

我的建议:不要重新发明轮子。

请参阅strtoul功能:

#include <stdlib.h>                                                             
#include <stdio.h>
int main(){

        /* first arg: number in base n to convert to base 10
         * third arg: base n
         */
        long int b10= strtoul("111",NULL,2);
        printf("%ld\n",b10);
        return 0;

}

答案 3 :(得分:1)

在您为其分配任何内容之前,您将添加到decValue。我没有仔细看你的逻辑,但立刻就突出了。取决于可能导致问题的平台。

答案 4 :(得分:1)

一些评论:

  1. 如上所述,您的代码不支持“任何基础”,最多只能支持17(一个奇怪的地方停止)。
  2. strchr()可以返回NULL。你永远不应该假设它不会,特别是当你直接用户输入时。
  3. 小写字母很好,你应该支持它们。只需使用toupper()将相关字符转换为大写字母,然后您就可以将aA识别为十六进制10。
  4. 为了编码实践,我建议创建一个函数来执行相关的转换,而不是在main()中完成所有脏工作。
  5. 如果您将此作为学习练习,请忽略此段落,但您似乎基本上正在重写标准库函数strtol(),该函数将字符串转换为long以获取任意基础。实际上,它非常好,并且有一些功能可以根据需要包含在代码中。

答案 5 :(得分:0)

偶然的事情:不要把input的地址(input,一个数组,已经降级到你想要的指针;取一个指针就会产生一个指向数组的指针,不是你想要的;);并且你需要确保在读入时不要溢出input缓冲区。

如果这不是作业,您应该使用strtol()

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

#define Str(x) #x
#define Xstr(x) Str(x)

int main()
{
    char input[LENGTH+1] ;
    int base;
    long decValue;
    char *endptr;

    puts( "Enter a value, and its base: " );
    scanf( "%" Xstr(LENGTH) "s", input ); /* reads at most LENGTH characters */
    scanf( "%i", &base );

    decValue = strtol( input, &endptr, base );
    assert( *endptr == '\0' ); /* if there are any characters left, then string contained invalid characters */

    printf( "%s (base-%u) equals %ld\n", input, base, decValue );

    return 0;
}