5进制转换.docx

上传人:b****3 文档编号:4958817 上传时间:2022-12-12 格式:DOCX 页数:22 大小:25.97KB
下载 相关 举报
5进制转换.docx_第1页
第1页 / 共22页
5进制转换.docx_第2页
第2页 / 共22页
5进制转换.docx_第3页
第3页 / 共22页
5进制转换.docx_第4页
第4页 / 共22页
5进制转换.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

5进制转换.docx

《5进制转换.docx》由会员分享,可在线阅读,更多相关《5进制转换.docx(22页珍藏版)》请在冰豆网上搜索。

5进制转换.docx

5进制转换

第5章进制转换问题

基础知识

5.1.1相关概念

1.数制

数制是人们利用符号进行计数的一种科学方法。

数制也称为计数制,是用一组固定的符号和统一的规则来表示数值的方法。

2.进制

进制也就是进位制,是人们规定的一种进位方法。

对于任何一种进制——X进制,就表示某一位置上的数运算时是逢X进一位。

十进制是逢十进一,十六进制是逢十六进一,二进制就是逢二进一。

3.数码

数制中表示基本数值大小的不同数字符号。

例如,十进制有10个数码:

0、1、2、3、4、5、6、7、8、9。

4.基数

数制所使用数码的个数。

例如,二进制的基数为2;十进制的基数为10。

5.位权

位权表示数的符号在不同的位置上时所代表的值是不同的。

也就是数制中某一位上的1所表示数值的大小(所处位置的价值)。

例如,十进制的123,1的位权是100,2的位权是10,3的位权是1。

5.1.2各种常见的进制

人们通常采用的进制有十进制、二进制、八进制和十六进制等。

1.十进制(Decimal)

十进制是人们日常生活中最熟悉的进位计数制。

在十进制中,数码共有0,1,2,3,4,5,6,7,8,9这十个符号。

计数规则是逢十进一。

2.二进制(Binary)

二进制是在计算机系统中采用的进位计数制。

二进制数有两个特点:

在二进制中,数码只有0和1两个符号。

计数规则是逢二进一。

为区别于其它进制数,二进制数的书写通常在数的右下方注上基数2,或在后面加上B表示。

例如:

二进制数可以写成()2,或写成B。

3.八进制数(Octal)

由于二进制数据的基数比较小,所以二进制数据的书写和阅读很不方便,为此,在小型机中引入了八进制。

八进制的基数R=8=23,有数码0、1、2、3、4、5、6、7,并且每个数码正好对应三位二进制数,所以八进制能很好地反映二进制。

八进制用下标8或数据后面加O表示例如:

二进制数据(11101010.010110100)2,对应的八进制数据8或。

4.十二进制(Duodecimal)

十二进制在生活中也是经常用到的,例如,长度单位一英尺等于12英寸,一先令等于12便士,就连足球比赛罚点球的英制长度也是12码。

此外还有一打12个,钟表转一圈12小时等等。

一般在十二进制中,10和11可用M和N表示,有时候也可用A和B表示。

5.十六进制(Hexadecimal)

十六进制是人们在计算机指令代码和数据的书写中经常使用的数制。

在十六进制中,由十六个字符0~9以及A,B,C,D,E,F(或a,b,…,f)组成(它们分别表示十进制数10~15)来描述。

计数规则是逢十六进一,即基数R=16=24,通常在表示时用尾部标志H或下标16以示区别。

例如:

十六进制数4AC8可写成(4AC8)16,或写成4AC8H。

6.六十进位制数(Sexagesimal)

古代人由于生产劳动的需要,要研究天文和历法,就牵涉到时间和角度了。

因为历法需要的精确度较高,时间的单位小时,角度的单位度都嫌太大。

必须进一步研究他们的小数。

它们的小数都具有这样的性质:

使1/2,1/3,1/4,1/5,1/6等都能成为他的整数倍。

以1/60作为单位,就正好具有这个性质。

譬如:

1/2等于30个1/60,1/3等于20个1/60,1/4等于15个1/60……这种小数的进位制在表示有些数时很方便。

例如常遇到的1/3,在十进位制中要变成无限小数,但在这种进位制中就是一个整数。

因此就出现了六十进制。

5.1.3进制转换

在实际运算中,我们经常用到各种不同的进制,这就需要在各种数制之间进行转换。

1.其他进制转换为十进制(按权求和)

方法是:

将其它进制按权位展开,然后各项相加,就得到相应的十进制数。

例1:

N=()B=()D

按权展开N=1*24+0*23+1*22+1*21+0*20+1*2-1+0*2-2+1*2-3

=16+4+2++=()D

例2:

(38A.11)16转换为十进制数

  (38A.11)16

  =3×162+8×161+10×160+1×16-1+1×16-2

  =768+128+10++

  =

2.十进制转换成其它进制

方法是:

分两部分分别进行的,即整数部分和小数部分。

(1)整数部分:

(基数除法)

把我们要转换的数除以新的进制的基数,把余数作为新进制的最低位;

把上一次得到的商再除以新的进制基数,把余数作为新进制的次低位;

继续上一步,直到最后的商为零,这时的余数就是新进制的最高位。

(2)小数部分:

(基数乘法)

把要转换数的小数部分乘以新进制的基数,把得到的整数部分作为新进制小数部分的最高位。

把上一步得的小数部分再乘以新进制的基数,把整数部分作为新进制小数部分的次高位;

继续上一步,直到小数部分变成零为止。

或者达到预定的精度要求或位数要求也可以。

3.二进制与八进制、十六进制的相互转换

二进制转换为八进制、十六进制:

它们之间满足23和24的关系,因此把要转换的二进制从低位到高位每3位或4位一组,高位不足时在有效位前面添“0”,然后把每组二进制数转换成八进制或十六进制即可。

八进制、十六进制转换为二进制时,把上面的过程逆过来即可。

也就是把一个八或十六进制位转换为3或4个二进制位。

例3:

N=(C1B)H=()B

(C1B)H=1100/0001/1011=()B

4.数制转换的一般化

(1)R进制转换成十进制

任意R进制数按权展开,相加即可得十进制数据。

例如:

N==1*23+1*22+0*21+1*20+0*2-1+1*2-2+0*2-3+1*2-4=8+4+0+1+0++0+=

N=5A.8H=5*161+A*160+8*16-1=80+10+=

(2)十进制转换R进制

十进制数转换成R进制数,须将整数部分和小数部分分别转换。

整数转换——除R取余法,规则:

1用R去除给定的十进制数的整数部分,取其余数作为转换后的R进制数据的整数部分最低位数字;

②再用R去除所得的商,取其余数作为转换后的R进制数据的高一位数字;

③重复执行②操作,直到商为0结束。

小数转换——乘R取整法,规则:

1用R去乘给定的十进制数的小数部分,取乘积的整数部分作为转换后R进制小数点后第一位数字;

②再用R去乘上一步乘积的小数部分,然后取新乘积的整数部分作为转换后R进制小数的低一位数字;

2重复②操作,一直到乘积为0,或已达到精度要求或位数要求为止。

解决数制转换问题时,如果所给的数值不是用十进制表示的,一般用一个字符型数组来存放。

数组的每个元素分别存储它的一位数字。

然后按位转换求和,得到十进制表示;再把十进制表示转换成所求的数制表示。

转换的结果也用一个字符型数组表示,每个元素表示转换结果的一位数字。

根据数制表示中相邻位的基数关系,可以把不同的数制分成两类。

一类数制表示中,相邻位的基数是等比关系,例如我们熟悉的十进制表示。

另一类数制表示中,相邻位的基数是不等比的。

例如在时间表示中,从秒到分采用60进进制;从月到年则采用12进制。

把一个数值从数制B的表示bmbm-1bm-2...b1转换成十进制表示dndn-1dn-2...d1比较简单。

假设数制B中,第i位的基数为basei(1<=i<=m),直接把basei与bi相乘,然后对全部乘积求和。

从十进制表示dndn-1dn-2...d1到bmbm-1bm-2...b1的转换需要分两种情况考虑:

数制B中相邻数字的基数是等比关系,即:

basei(1<=i<=m)可以表示成Ci-1,其中C是一个常量。

将dndn-1dn-2...d1除以C,余数即为b1;将dndn-1dn-2...d1和C相除的结果再除以C,余数即为b2;…;直至计算出为bm止。

数制B中相邻数字的基数不等比。

需要先判断dndn-1dn-2...d1在数制B中需要的位数m,然后从高位到低位依次计算bm、bm-1、bm-2、...、b1。

例5001特殊的四位数

(来源:

2405/2196)

问题描述:

找出并输出所有的4位数(十进制数)中具有如下属性的数:

四位数字之和等于其十六进制形式各位数字之和,也等于其十二进制形式各位数字之和。

例如:

十进制数2991,其四位数字之和2+9+9+1=21。

由于2991=1*1728+8*144+9*12+3,其十二进制形式为1893(12),其各位数字之和也为21。

但是它的十六进制形式为BAF(16),其各位数字之和等于11+10+15=36。

因此你的程序要舍去2991这个数据。

下一个数2992,其十进制、十二进制、十六进制形式各位数字之和均为22,因此2992符合要求,应该输出来。

(只考虑4位数,2992是第一个符合要求的数)

输入:

本题没有输入。

输出:

你的程序要求输出2992及其他更大的、满足要求的四位数(要求严格按升序输出),每个数占一行(前后都没有空行),整个输出以换行符结尾。

输出中没有空行。

输出中的前几行如输出样例所示。

输入样例:

本题没有输入。

输出样例:

2992

2993

2994

2995

2996

2997

2998

2999

...

解题分析:

该题在求解时要用到枚举的算法思想,即枚举所有的四位数(1000-9999),判断其是否满足十六进制、十二进制和十进制形式的各位数之和相等。

由于题目已经告诉你3000以内的所有满足条件的数,因此我们可以直接输出这些数,从3000开始枚举。

将一个十进制数N转换到B进制,其方法是:

将N除以B取余数,直到商为0为止,存储得到的余数,然后逆序输出余数即可得到B进制下的数,但由于此题只需要得到N在16、12和10进制下各位的和,所以不需要对余数逆序,直接累加其余数即可。

参考程序(zzg):

#include<>

#include<>

#include<>

intbase(intb,intn)

{

intsum=0;

while(n!

=0)

{

sum+=n%b;

n/=b;

}

returnsum;

}

intmain()

{

inti,a;

printf("2992\n2993\n2994\n2995\n2996\n2997\n2998\n2999\n");

for(i=3000;i<10000;i++)

{

a=base(12,i);

if(base(10,i)==a&&a==base(16,i))

{

printf("%d\n",i);

}

}

return0;

}

例5002进制转换

(来源:

2031)

问题描述:

输入一个十进制数N,将它转换成R进制数输出。

输入:

输入数据包含多个测试实例,每个测试实例包含两个整数N(32位整数)和R(2<=R<=16,R<>10)。

输出:

为每个测试实例输出转换后的数,每个输出占一行。

如果R大于10,则对应的数字规则参考16进制(比如,10用A表示,等等)。

输入样例:

72

2312

-43

输出样例:

111

1B

-11

解题分析:

这题就是考察十进制转换为其他进制的用法,由于需要转换的是整数,因此只需要把十进制整数除以R取余即可。

这里可以采用循环或递归来实现即可。

由于R不确定,因此我们可以编写个函数来实现十进制转换为R进制的功能。

参考程序(hxx):

#include<>

intTenToR(intnum,intr)

{

charm;

if(num==0)

return0;

TenToR(num/r,r);

m=(num%r>9num%r-10+'A':

num%r+'0');

printf("%c",m);

}

intmain()

{

intn,r;

while(scanf("%d%d",&n,&r)!

=EOF)

{

if(!

n)

printf("0");

elseif(n>0)

TenToR(n,r);

else

{

printf("-");

TenToR(-n,r);

}

printf("\n");

}

return0;

}

例5003skew数

(来源:

2973)

问题描述:

在skew二进制数表示中,第k位的值xk表示xk*(2k+1-1)。

每个位上的可能数字是0或1,最后面一个非零位可以是2,例如,10120(skew)=1*(25-1)+0*(24-1)+1*(23-1)+2*(22-1)+0*(21-1)=31+0+7+6+0=44.前十个skew数是0、1、2、10、11、12、20、100、101以及102。

输入:

输入包含一行或多行,每行包含一个整数n。

如果n=0表示输入结束,否则n是一个skew数。

输出:

对于每一个输入,输出它的十进制表示。

转换成十进制后,n不超过231-1=2147483647。

输入样例:

10120

0000000000000000000000

10

000000000000000000

11

100

0000

0

输出样例:

44

46

3

47

4

7

37

解题分析1:

由于n不超过231-1,因此可以直接用int类型来保存n,位权可以采用移位来实现。

参考程序1(hsl):

#include<>

#include<>

#include<>

intmain(){

charstr[1010];

while(scanf("%s",str)!

=EOF){

if(strcmp(str,"0")==0)break;

intl=strlen(str);

inti,j,ans=0,t1=1,t2;

for(i=l-1;i>=0;i--){

t1=t1<<1;

t2=t1-1;

ans+=(str[i]-'0')*t2;

}

printf("%d\n",ans);

}

return0;

}

解题分析2:

由于skew数位数比较多,超过了int的范围,因此我们只能采用字符数组的形式来接收输入。

这里,最大的skew二进制数对应到十进制数为231-1=47,对应的skew数为:

000000000000000000。

一共31位,因此采用长度为32的字符数组即可。

剩下的工作就是按位权展开求和就能得到想要的结果。

参考程序2:

#include<>

#include<>

#include<>

intmain()

{

charstr[32];//读入的每个skew二进制数

while(scanf("%s",str)!

=EOF)

{

intlen=strlen(str);

intnum=0;//对应的十进制数

if(len==1&&str[0]=='0')break;

intweight=2;//每位的权值为weight-1

inti;

for(i=len-1;i>=0;i--)

{

num+=(str[i]-'0')*(weight-1);

weight*=2;

}

printf("%d\n",num);

}

return0;

}

例5004周易

(来源:

2989)

问题描述:

有人说,中国古代的“周易”是二进制系统的起源,在该系统中,他们用“--”表示1,“---”表示0。

因此,二进制数字“011010”可以表述为“---\n--\n--\n---\n--\n---\n”(符号“\n”表示换行)。

现在的问题是如何把一个十进制数转换为“周易”中的二进制

输入:

文件中包含多组测试数据。

每个测试数据占一行,包括一十进制整数n(0<=n<=1000000)和表示二进制位数的k(0

n=0,k=0表示输入结束。

输出:

对于每组测试数据,输出“周易”中对应的k行二进制数。

每组测试数据之间输出一个空行。

输入样例:

73

03

266

00

输出样例:

--

--

--

---

---

---

---

--

--

---

--

---

解题分析:

这题首先要把十进制数转换为二进制数,这个可以采用除2取余,再逆序输出即可。

其次就是如何输出k位,这里可能涉及到两种情况,一是k要大于实际二进制数的位数,那么前面需要用0来填补。

二是k小于实际的位数,那么需要在输出时控制只输出前k位(这里不会出现这种情况,因为题目中已经明确了n<2^k)。

由于k>0且k<=20,因此我们可以使用一个20位长的整数数组来存储转换后的二进制数,初始化时全部为0。

参考程序(hxx):

#include<>

#include<>

intmain()

{

inta[20];

intn,k;

inti;

while

(1)

{

scanf("%d%d",&n,&k);

if(n==0&&k==0)

break;

for(i=0;i<20;i++)

a[i]=0;

i=0;

while(n)

{

a[i++]=n%2;

n=n/2;

}

for(i=k-1;i>=0;i--)

{

if(a[i]==1)

printf("--\n");

else

printf("---\n");

}

printf("\n");

}

return0;

}

例5005奶牛计算器

(来源:

3191)

问题描述:

由于缺乏数学经验,奶牛想建立一个计算机器(它被称为Cowmpouter),使用二进制数字(基数为2),但它是建立在-2的基础上。

他们非常高兴,因为在-2进制表示的数字中不需要符号位。

你知道基数的权值都是从1开始的(0位),然后从右到左依次为基数1次方,基数2次方等等。

在-2进制中,其权值从右到左,依次为1,-2,4,-8,16,-32,…。

因此,从1计数依次是:

1,110,111,100,101,11010,11011,11000,11001等等。

很怪异的是,负数也那个用1和0表示,但没有符号位。

从-1向下计数依次为:

11,10,1101,1100,1111等等。

请帮助奶牛把普通的十进制整数(范围为:

-2,000,000,000到2,000,000,000)转换为-2进制对应的数。

输入:

输入只有一行,一个需要转换为-2进制的十进制整数。

输出:

对应的-2进制的数,没有前导0,0就表示0本身,只用1个0。

输入样例:

-13

输出样例:

110111

解题分析:

此题的解法基于以下几点:

(1)如果一个数是奇数,那么它的二进制形式的最后一位肯定是1,我们可以去掉此1,就是(x-1)/-2,进入

(2)。

(2)如果一个数的最后一位为0,我们可以把这个数右移(可以类比以2为基的二进制数的操作)一位,然后它的二进制的倒数第二个数就成了最后一个,就是x=x/-2,然后进入

(1)迭代,直到变为0。

参考程序(hxx):

#include<>

#include<>

intvalue;

charcache[100];

intcnt;

voidreverse()

{

inti;

chartmp;

for(i=0;i

{

tmp=cache[cnt-i-1];

cache[cnt-i-1]=cache[i];

cache[i]=tmp;

}

}

intmain()

{

scanf("%d",&value);

if(value==0)

{

printf("0");

gotoend;

}

while(value!

=1)

{

if(abs(value)%2!

=0)

{

cache[cnt++]='1';

value=(value-1)/(-2);

}

else

{

cache[cnt++]='0';

value=value/(-2);

}

}

reverse();

cache[cnt]='\0';

printf("1%s",cache);

end:

;

return0;

}

例5006计算器设计

(来源:

1546/1334)

问题描述:

ReallyNeato计算器公司最近邀请你的团队为他们设计一款超级Neato一代计算器。

作为计算机科学家,你建议该计算器能够在各种进制之间进行转换。

他们认为这是一个很好的想法,并要求你的团队先给出实现进制转换的算法原型。

公司经理告诉你,该计算器应该具有以下一些特征:

(1)可以显示7位;

(2)按键除了数字0到9外,还包括大写字母A到F;

(3)支持2~16进制。

输入:

输入文件中的每行为一个进制转换,包括3个数,第1个数是原进制下的一个整数,第2个数就是原进制,第3个数是转换后的进制。

这3个数的两边可能有一个或多个空格。

输入数据一直到文件结尾。

输出:

实现所有的进制转换,转换后的数右对齐到7位显示。

如果转换后的数的位数太多,超过7位,则输出“ERROR”,也是右对齐到。

输入样例:

1111000210

1111000216

2102101310

2102101315

1231242

1A152

12345671016

ABCD1615

输出样例:

120

78

1765

7CA

ERROR

11001

12D687

D071

参考程序(zzg):

#include<>

#include<>

longb2ten(char*x,intb);

intmain()

{

charnumsrc[10],numdest[10];//用来存储读入的数和转换后的数

chartemp[10];

charerror[10]="ERROR";

longnum;

intsrc,dest;//转换前的进制和转换后的进制

inti,j;

//freopen("","r",stdin);

while(scanf("%s%d%d",numsrc,&src,&dest)!

=EOF)

{

//先把src进制的数转换为10进制数,存放到temp中

num=b2ten(numsrc,src);

if(dest==10)

{

if(num>9999999)

printf("%7s\n",error);

else

printf("%7d\n",num);

}

else

{

i=0;

while(num)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1