首页 > 代码库 > 大整数进制转换

大整数进制转换

题目描述:

将一个长度最多为30位数字的十进制非负整数转换为二进制数输出。

输入:

多组数据,每行为一个长度不超过30位的十进制非负整数。
(注意是10进制数字的个数可能有30个,而非30bits的整数)

输出:

每行输出对应的二进制数。

样例输入:
0
1
3
8
样例输出:
0
1
11
1000
来源:
2008年北京大学软件所计算机研究生机试真题
1.自己想的解法特别的复杂
#include<stdio.h>
#include<string.h>
//基本思路,先把大整数拆成几个部分,用二进制算最终结果
int DtoB (char b[],char str[],int len){//转十进制到二进制
    int tmp=0;
    int i;
    if(len==0) {
        b[0]=0;
        return 0;
    }
    for(i=len-1;i>=0;--i){
        tmp*=10;
        tmp+=(str[i]-0);
    }
    i=0;
    do{
        b[i++]=tmp%2+0;
        tmp/=2;
    }while(tmp!=0);
    b[i]=0;
    return i;//返回位数
}
int Badd(char b1[],int size1,char b2[],int size2){//二进制加法,最终放在b2,从低位到高位
    int i;
    int c;//进位
    int x;
    if(size1<=size2){
        c=0;
        for(i=0;i<size1;i++){
            x=c+b1[i]-0+b2[i]-0;
            b2[i]=x%2+0;
            c=((x>=2)?1:0);
        }
        for(i=size1;i<size2;i++){
            x=c+b2[i]-0;
            b2[i]=x%2+0;
            c=((x>=2)?1:0);
        }
        if(c==1) b2[i++]=1;
        b2[i]=0;
        return i;
    }
    else{
        c=0;
        for(i=0;i<size2;i++){
            x=c+b1[i]-0+b2[i]-0;
            b2[i]=x%2+0;
            c=((x>=2)?1:0);
        }
        for(i=size2;i<size1;i++){
            x=c+b1[i]-0;
            b2[i]=x%2+0;
            c=((x>=2)?1:0);
        }
        if(c==1) b2[i++]=1;
        b2[i]=0;
        return i;
    }
}
int Bmul(char b[],int len){//二进制乘以10
    char bmul2[100];//原来的二进制乘二,就是右移一位
    int i;
    for(i=len;i>=0;i--){//包括\0右移
        bmul2[i+1]=b[i];
    }
    bmul2[0]=0;//第0位补0
    for(i=len;i>=0;i--){//乘8,右移3位
        b[i+3]=b[i];
    }
    b[0]=b[1]=b[2]=0;
    int size=Badd(bmul2,len+1,b,len+3);//最终结果在b里面,size返回大小
    return size;

    
}

int main(){
    char str[31];//大整数
    while(scanf("%s",str)!=EOF){

        int size=strlen(str);
        char str1[11],str2[11],str3[11],str4[11];//把十进制字符串拆成4段str1->str3 低位到高位 9位9位分割
        int i,j,size1=0,size2=0,size3=0,size4=0;
        for (i=0;i<11;i++){
            str1[i]=0;
        }
        for (i=0;i<11;i++){
            str2[i]=0;
        }
        for (i=0;i<11;i++){
            str3[i]=0;
        }
        for (i=0;i<11;i++){
            str4[i]=0;
        }

        for(size1=0,j=size-1;size1<9&&j>=0;++size1,--j){
            str1[size1]=str[j];
        }
        str1[size1]=0;
        for(size2=0;size2<9&&j>=0;++size2,--j){
            str2[size2]=str[j];
        }
        str2[size2]=0;
        for(size3=0;size3<9&&j>=0;++size3,--j){
            str3[size3]=str[j];
        }
        str3[size3]=0;
        for(size4=0;size4<9&&j>=0;++size4,--j){
            str4[size4]=str[j];
        }
        str4[size4]=0;
        
        char b1[150],b2[150],b3[150],b4[150];//二进制形式的各段,0位放最低位二进制—>高
        int b1_size=DtoB(b1,str1,size1);
        int b2_size=DtoB(b2,str2,size2);
        int b3_size=DtoB(b3,str3,size3);
        int b4_size=DtoB(b4,str4,size4);
        //int sizea=Badd(b2,b2_size,b1,b1_size);//以上都正确
        //int sizea=Bmul(b2,b2_size);//
        if(b2_size!=0){
            for(i=0;i<9;i++){
                b2_size=Bmul(b2,b2_size);
            }
            b1_size=Badd(b2,b2_size,b1,b1_size);
        }
        if(b3_size!=0){
            for(i=0;i<18;i++){
                b3_size=Bmul(b3,b3_size);
            }
            b1_size=Badd(b3,b3_size,b1,b1_size);
        }
        if(b4_size!=0){
            for(i=0;i<27;i++){
                b4_size=Bmul(b4,b4_size);
            }
            b1_size=Badd(b4,b4_size,b1,b1_size);
        }

        for(i=b1_size-1;i>=0;--i){
            printf("%c",b1[i]);
        }
        printf("\n");
        
    }


return 0;
}

2.在网上看到大整数十进制转六进制的解法(来源:十进制大整数转换成十六进制数

Description

将十进制数转换成十六进制数。

Input

包括多组测试数据。输入一个不超过100位正整数,无前导零。
输入以0结束。

Output

输出其十六进制表示(不打印前导零,A~F字母大写)。

Sample Input

12
20
12345678901234567890
0

Sample Output

C
14
AB54A98CEB1F0AD2
原理:16的倍数乘以625一定能被10000整除,那么一个整数乘以625所得数的最后4位除以625所得值等价于这个整数对16取余。
#include<stdio.h>
#include<string.h>
void main()
{
    int i,j,a[110],b[110],t;
    char s[105];
    while(gets(s),strcmp(s,"0")){
        strrev(s);
        for(i=0;i<110;i++)a[i]=b[i]=0;
        for(i=0;s[i];i++)a[i]=s[i]-48;//将字符转化为数字
        for(t=1;t<100;t++){
            for(i=0;i<110;i++)a[i]*=625;
            for(i=0;i<110;i++){
                if(a[i]>9){
                    a[i+1]+=a[i]/10;
                    a[i]%=10;
                }
            }
            b[t]=(a[0]+a[1]*10+a[2]*100+a[3]*1000)/625;//求余数
            for(i=0;i<105;i++)a[i]=a[i+4];//去掉余数
        }
        for(;!b[t]&&t>1;t--);//去掉前导零
        for(;t;t--)printf("%X",b[t]);
        puts("");
    }
}

3.用相似的原理

大整数进制转换