进制是计算机科学中的一个基本概念。在计算机内部无论是数据还是程序代码均用0、1序列来表示,也就是说,在计算机内部使用的是二进制。二进制是计算机科学的基础。除二进制外,在数据的输入、输出,数据的表示、运算,数据的传输、通信等过程中,八进制、十进制、十六进制也发挥着广泛而重要的作用。除了以上较为熟悉的进制外,在日常生活中,还大量使用着各种不同的进制,如十二进制(12件物品为一打,12个月为一年),二十四进制(24小时为一天),六十进制(如分、秒的计时)等等,如此众多的进制表示常常会给我们带来诸多不便。因此,我们根据进制的基本概念和进制转换的基本原理用C语言开发了一个万能进制转换程序,可以在任意进制间相互转换。
一、进制的基本概念
将数字符号按先后次序排列成数位,并遵照某种由低位到高位的进位方式来表示数值的方法,称为进位计数制,简称进制。
进制是一种计数方法,根据进制的基数不同,可以分为多种进制。其中,最常用的是十进制,十进制的基数为十,由十个基本符号0、1、2、3、4、5、6、7、8、9组成,相同数字符号在不同的数位上表示不同的数值,每个数位计满十就向其高位进一,即“逢十进一”。如十进制数 555,第一个5表示500,第二个5表示50,第三个5表示5。即555=5×102+5×101+5×100。二进制是整个计算机学科的基础,它的基数为二,有0、1两个基本符号,逢二进一。如1101=1×23+1×22+0×21+1×20。由此我们可以得到进制表示的一般规律:
J进制的基数为J,由J个基本符号组成,分别为0~J-1,每个数位满J向其高位进一,即逢J进一。设N是一个J进制数,N=knkn-1...k0,则N可展开为:
N=knJn+ kn-1 Jn-1+……+k0J0
这种进制计数方法是人类千百年来社会劳动生活的智慧结晶,它简单、直观、灵活、实用,特别是相同数字符号在不同的数位上表示不同的数值,使得可以通过位置的改变减少基本符号的个数。 需要说明的是,在本程序中当J≤10时,基本符号为0~J-1,如二进制的基本符号为0、1,八进制的基本符号为 1、2、3、4、5、6、7;当11≤J≤36时,用A,B,C,……,X,Y,Z(大小写均可)分别表示10,11,12,……,33,34,35,如十六进制的基本符号为0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F,其中A~F分别表示10~15,二十进制的基本符号为0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F、G、H、I、J,其中A~J分别表示10~19;当J≥37时,基本符号为0~J-1,但要注意在输入、输出时任两位之间以空格分开,如以 1 36 30 表示一个40进制的数时,这是一个三位数,第一位为 1,第二位为36,第三位为30。
二、进制的转换
由于我们对十进制非常熟悉,因此在m进制转为n进制时以十进制作为中转。
1、m进制转为十进制
设N是一个m进制数,N=knkn-1...k0,则N可展开为:
N=knmn+ kn-1 mn-1+……+k0m0
将等号右边按十进制数的加法和乘法运算规则运算所得的数即为转换所得的十进制数。
2、十进制转为n进制 设N 为一个十进制数,将N除以n得到一个余数和一个整数商,记下该余数。然后再用这个整数商去除以n又得到一个余数和一个整数商,记下该余数。如此反复,直到整数商为零。这样我们就得到一个余数串,将该余数串反序,就得到了我们所要求的n进制数。例如,十进制数12转为2进制数,不断除以2,所得余数串为0011将其反序1100即为所求。
三、程序清单
#include
#include
#include
#include
#include
#define MAXLEN 100
unsigned int check(char *s,unsigned int m);
void strtonum(char* str,unsigned int *p,unsigned int m);
unsigned long mto10(int *p,unsigned int mlen,unsigned int m);
void tenton(unsigned long l10,int *p,int n,unsigned int nlen);
void main()
{
unsigned int m,n,mlen,nlen;
char snumber[MAXLEN];
unsigned int* p;
unsigned long l10;/*l10为m进制转为n进制时作为中转的十进制数*/
int i;
printf("万能进制转换程序。请输入欲转换的数:n");
gets(snumber);/*将输入的m进制数作为一个字符串接收*/
printf("m进制转为n进制,请输入m和n:n");
printf("m=");scanf("%u",&m);
printf("n=");scanf("%u",&n);
if(m<2||n<2){printf("非法输入!");exit(0);}
mlen=check(snumber,m);
p=malloc(sizeof(int)*mlen);
strtonum(snumber,p,m);
l10=mto10(p,mlen,m);
free(p);
nlen=log(l10)/log(n);/*求出将十进制数l10转为n进制数时该n进制数的位数*/
p=malloc(sizeof(int)*nlen);
tenton(l10,p,n,nlen);
printf("转为:");
for(i=0;i<=nlen;i++)
{
if(n>36)printf("%u ",p[i]);
else
{
if(p[i]>=10)printf("%c",p[i]+A-10);
else printf("%d",p[i]);
}
}
printf("n");
free(p);
}
unsigned int check(char *s,unsigned int m)
/*将输入的m进制数字符串全部转为大写并返回有效的m进制数的位数*/
{
unsigned int i=0,num=0;
strupr(s);
while(s[i]!=)
if(s[i++]== )num++;
if(m>36)return num+1;
else return strlen(s)-num;
}
void strtonum(char* str,unsigned int *p,unsigned int m)
/*将输入的m进制数字符串一位一位转为数字并放入数组p中*/
{
int i=0,j=0;
char *q;
if(m>36)
{
q=strtok(str," ");p[i++]=atoi(q);
while(q){q=strtok(NULL," ");p[i++]=atoi(q);}
}
else
{
while(str[i]!=)
{
if(isalpha(str[i]))p[j++]=str[i]-A+10;
else if(isdigit(str[i]))p[j++]=str[i]-0;
i++;
}
}
}
unsigned long mto10(int *p,unsigned int mlen,unsigned int m)
/*将数组p中按位存放的m进制数转为十进制数并返回*/
{
unsigned long l=0,h;
int i,j;
for(i=mlen-1;i>=0;i--)
{
h=1;
for(j=1;j<=i;j++)h*=m;
l+=p[mlen-1-i]*h;
}
return l;
}
void tenton(unsigned long l10,int *p,int n,unsigned int nlen)
/*十进制转为n进制*/
{
unsigned long a=l10;
while(a)
{
p[nlen--]=a%n;
a/=n;
}
}
本程序为标准C程序,适用于DOS或UCIX环境,并在Turbo C 2.0,586兼容机下编译通过。另外,本程序的操作数不能超过C语言中的无符号最大长整数4294967295
四、程序运行实例
1、万能进制转换程序。请输入欲转换的数:
1 2 3 99
m进制转为n进制,请输入m和n:
m=100
n=10
转为:1020399
2、万能进制转换程序。请输入欲转换的数:
1234567890
m进制转为n进制,请输入m和n:
m=10
n=8
转为:11145401322
3、万能进制转换程序。请输入欲转换的数:
123abc
m进制转为n进制,请输入m和n:
m=16
n=2
转为:100100011101010111100
4、万能进制转换程序。请输入欲转换的数:
1111111111111111
m进制转为n进制,请输入m和n:
m=2
n=20
转为:83GF
5、万能进制转换程序。请输入欲转换的数:
77777777
m进制转为n进制,请输入m和n:
m=8
n=40
转为:6 22 5 30 15
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28429/viewspace-846488/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/28429/viewspace-846488/