首页 > 代码库 > 高精度进制转换

高精度进制转换

高精度进制转换:

       对于普通的不是很大的数的相互转换,我们一般采用不断模取余的方法,例如:将10进制数m转换成n进制数,则对m模n取余即可。但是,如果是一个有几百、几千或者更多位的大数呢?显然这种模取余的方法不再适用了。那如何求解此类大数的转换呢?接下来,介绍一种通用方法。

        我们将一个大数的每一位看做是一个单独的数,但是却不是完全孤立的,与其它位置上的数有关联,从该数的最高位开始,对该位上的数除以要转换的进制基数,得到商和余数,商取代原来该位上的数,进行下一位的相同操作,但是注意下一位的除数不仅仅是该位的数,而是前一次的余数乘以大数的进制基数加上该位的数,如此循环,到所以位都除过一次,记录最后一位操作得到的余数,然后将上次的商作为除数,继续上次的操作,直到商为零。逆序输出每次记录的余数,即是要求的数。








接下来提供一些函数,仅供参考:(以下函数是1到62进制的相互转换,其中定义0=0,1=1,……,9=9,A=10,B=11,……Y=34,Z=35,a=36,b=37,……,y=60,z=61。

第一个函数:将字符转换成对应进制的整数

代码如下:C代码

#include<stdio.h>
#include<string.h>
//第一个函数
int GetNum(char c)//将字符转换成对应进制的整数
{
    if(c>='0'&&c<='9') return c-'0';
    if(c>='A'&&c<='Z' ) return c-'A'+10;
    return c-'a'+36;
}

int main()
{
    int i,n;
    char str[100];
    scanf("%s",str);
    n=strlen(str);
    for(i=0;i<n-1;i++)
        printf("%d ",GetNum(str[i]));
    printf("%d\n",GetNum(str[n-1]));
    return 0;
}

第一行是输入,第二行到第四行是输出。



第二个函数:将对应进制整数转换成对应的字符

代码如下:C代码

#include<stdio.h>
#include<string.h>
//第二个函数
char GetChar(int i)//将对应进制整数转换成对应的字符
{
    if(i>=0&&i<=9) return i+'0';
    if(i>=10&&i<=35) return i-10+'A';
    return i-36+'a';
}

int main()
{
    int i,n,num;
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%d",&num);
        printf("%c ",GetChar(num));
        if(i==9||i==35)
            printf("\n");
    }
    return 0;
}

    一至四行是输入,最后三行是输出。

   

还有几个函数,但是要调用其它函数,在这里整体给出(请详细看代码及注释):

代码如下:C/C++代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE 600//大数的最大位数
char str[MAXSIZE];//储存需要转换的大数,以字符形式储存
//oldbase:原基数;newbase:新基数;len:大数的长度
int oldbase,newbase,len,k;
//a[MAXSIZE];储存大数的最小整型,注意a[0]没有使用;r[MAXSIZE]:储存余数,即所求数的每一位
int a[MAXSIZE],r[MAXSIZE];
int GetNum(char c)//将字符转换成对应进制的整数
{
    if(c>='0'&&c<='9') return c-'0';
    if(c>='A'&&c<='Z' ) return c-'A'+10;
    return c-'a'+36;
}
char GetChar(int i)//将对应进制整数转换成对应的字符
{
    if(i>=0&&i<=9) return i+'0';
    if(i>=10&&i<=35) return i-10+'A';
    return i-36+'a';
}
void ChToNum()//调用函数将字符串转化成对应进制的整数,按位转化
{
    len=strlen(str);//测量字符串的长度
    //遍历每一个字符,一一对应转化,注意没有使用a[0]
    for(int i=1;i<=len;i++)
    {
        a[i]= GetNum(str[i-1]);
    }
}
void alter()//转化函数,核心代码
{
    int m=1;
    k=0;
    while(m<=len)
    {
        int i,t = 0;
        //对数的每一位除新基数求商求余
        for(i=m;i<=len;i++)
        {
            t=t*oldbase+a[i];//计算除数
            a[i]=t/newbase;//求商
            t%=newbase;//求余
        }
        r[k++]=t;//记录最后一个余数
        for(i=1;i<=len&&!a[i];i++);//去除前导0
        m=i;
    }
}
void print()//输出函数
{
    printf("%d %s\n%d ",oldbase,str,newbase);
    while(k--)//逆序输出余数,即是结果
    {
        printf("%c",GetChar(r[k]));
    }
    printf("\n\n");
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        while(n--)
        {
            scanf("%d %d %s",&oldbase,&newbase,str);
            ChToNum();//字符转换为整型
            alter();//转化
            print();//函数调用输出结果
        }
    }
    return 0;
}
输入:

8

62  2  abcdefghiz

10  16  1234567890123456789012345678901234567890

16  35  3A0C92075C0DBF3B8ACBC5F96CE3F0AD2

35  23  333YMHOUE8JPLT7OX6K9FYCQ8A

23  49  946B9AA02MI37E3D3MMJ4G7BL2F05

49  61  1VbDkSIMJL3JjRgAdlUfcaWj

输出: