32位二进制到十进制转换

时间:2014-05-28 17:51:17

标签: c recursion binary

我有这个代码从二进制到十进制:

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

int main() {                                                                     

   printf("%lld\n", binaryToDecimal(11110000111100001111000011110000));            
   return 1;                                                                            
}                                                                                
long long binaryToDecimal(long long binary) {                                          
      int power = 0;                                                        
      return binaryToDecimalHelper(binary, power);                             

}                                                                                

long long binaryToDecimalHelper(long long binary, int power) {                      
    if (binary != 0) {                                                       
            long long i = binary % (double)10;                                  
            return (i * pow(2, power))                     
                            + binaryToDecimalHelper(binary / 10, power + 1); 
    } else {                                                                 
            return 0;                                                        

    }                                                                        
}                          

它适用于小值(最多16位),但对于32位(这是我需要的)它只返回垃圾。

4 个答案:

答案 0 :(得分:3)

数字11110000111100001111000011110000的类型为int,它不能在您的机器中保存一个大到11110000111100001111000011110000的数字。如果可以的话,最好使用字符串表示(&#34; 11110000111100001111000011110000&#34;)并调整算法。

答案 1 :(得分:1)

如果限制为最多32位,这是一个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void setStr(char *c, const char * x)
{
    int i = 0;
    while(x[i] != '\0')
    {
        c[i] = x[i];
        i++;
    }
}

void prepend(char* s, const char* t)
{
    size_t len = strlen(t);
    size_t i;
    memmove(s + len, s, strlen(s) + 1);
    for (i = 0; i < len; ++i)
    {
        s[i] = t[i];
    }
}

int main(int argc, char const *argv[])
{
    char *x = malloc(33*sizeof(char));
    setStr(x, "111");
    while (strlen(x) < 31) // not really necessary, but will help to 'cut' bytes if necessary
    {
        prepend(x,"0");
    }
    printf("%s\n", x);
    int i = strtol(x,NULL,2);
    printf("%d\n",i);
    free(x);
    return 0;
}

答案 2 :(得分:1)

首先要明确的是,您的代码不会将任何内容转换为 decimal ,而是转换为 int 。转换为该整数的十进制字符串表示printf()调用执行。

文字常量11110000111100001111000011110000由编译器解释(或者如果它不是那么大)作为十进制值,因此需要104位来存储;

即。 log10(11110000111100001111000011110000 10 )/ log10(2 10

使用仅包含1位和0位的十进制整数表示二进制值并没有多少数学意义 - 尽管它可能对小整数很方便。 64位unsigned long long仅适用于20个十进制数字(仅使用1和0 - 它可以表示所有19位正十进制整数,以及一些20位数值);

即。 log10(2 10 )* 64 10

如果您需要更长的二进制值,那么您应该使用字符串表示。事实上,这在任何情况下都更简单,更有效 - 您可以使用整数的机器表示已经是二进制的事实:

#include <stdio.h>                                                               
#include <stdint.h>                                                              

uint64_t binstrToInt( const char* binstr ) 
{          
    uint64_t result = 0 ;
    int bit = 0; 
    while( binstr[bit] != '\0' )
    {
        if( binstr[bit] == '1' )
        {
            result |= 1 ;
        }

        bit++ ;
        if( binstr[bit] != '\0' )
        {
            result <<= 1 ;
        }
    }

    return result ;
}                                                                                

int main() 
{                                                                     
    printf("%llu\n", binstrToInt( "11110000111100001111000011110000" ) ) ;            

    return 0 ;                
}                                                                                

答案 3 :(得分:0)

到目前为止,这将是一个最简单的字符串作为输入而不是int,并允许更长的数字。您的问题可能是由整数溢出引起的。

字符串版本:

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

int main() {

    const char * const string_to_convert = "1010"
    int result = 0;

    for( int i = strlen(string_to_convert) - 1; i >= 0; --i ) {
        if( string_to_convert[i] == '1' ) {
            // Careful with pow() -- returns double, may round incorrectly
            result += (int)pow( 10.0d, (double)i )
        }
    }

    fprintf( stdout, "%d", result );

    return 0;
}

另外,我不确定return 1是什么意思。通常,main的非零返回值表示错误。