十进制数转换为二进制数时,由于整数和小数的转换方法不同,所以先将十进制数的整数部分和小数部分分别转换后,再加以合并
最近在学习计算机基础 研究到进制转换,颇有心得,在此做个解释和记录;
首先介绍 二进制转换十进制
二进制数第0位的权值是2的0次方,第1位的权值是2的1次方……所以,设有一个二进制数:101100100,转换为10进制为:356用横式计算(从右往左算)0×20+0×21+1×22+0×23+0×24+1×25+1×26+0×27+1×28=3560乘以多少都是0,所以我们也可以直接跳过值为0的位:1×22+1×25+1×26+1×28=3564+32+64+256 =356然后介绍 十进制转换二进制
十进制转换2进制的方法可以总结的说 就是除2取余 除二取余······
例如
画图来说:
十进制数转换为二进制数时,由于整数和小数的转换方法不同,所以先将十进制数的整数部分和小数部分分别转换后,再加以合并
要从右到左用二进制的每个数去乘以2的相应次方,小数点后则是从左往右1101.01(2)=1*20+0*21+1*22+1*23 +0*2-1+1*2-2=1+0+4+8+0+0.25=13.25(10)所以总结起来通用公式为:abcd.efg(2)=d*20+c*21+b*22+a*23+e*2-1+f*2-2+g*2-3(10)或者用下面这种方法:把二进制数首先写成加权系数展开式,然后按十进制加法规则求和。这种做法称为"按权相加"法。2的0次方是1(任何数的0次方都是1,0的0次方无意义)2的1次方是22的2次方是42的3次方是82的4次方是162的5次方是322的6次方是642的7次方是1282的8次方是2562的9次方是5122的10次方是10242的11次方是20482的12次方是40962的13次方是81922的14次方是163842的15次方是327682的16次方是655362的17次方是1310722的18次方是2621442的19次方是5242882的20次方是1048576即:此时,1101=8+4+0+1=13再比如:二进制数100011转成十进制数可以看作这样:数字中共有三个1 即第一位一个,第二位一个,第六位一个,然后对应十进制数即2的0次方+2的1次方+2的5次方, 即100011=32+0+0+0+2+1=351. 十进制整数转换为二进制整数 十进制整数转换为二进制整数采用"除2取余,逆序排列"法。具体做法是:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。十进制整数转二进制如:255=(11111111)B255/2=127=====余1127/2=63======余163/2=31=======余131/2=15=======余115/2=7========余17/2=3=========余13/2=1=========余11/2=0=========余1789=1100010101(B)789/2=394 余1 第10位394/2=197 余0 第9位197/2=98 余1 第8位98/2=49 余0 第7位49/2=24 余1 第6位24/2=12 余0 第5位12/2=6 余0 第4位6/2=3 余0 第3位3/2=1 余1 第2位1/2=0 余1 第1位原理:众所周知,二进制的基数为2,我们十进制化二进制时所除的2就是它的基数。谈到它的原理,就不得不说说关于位权的概念。某进制计数制中各位数字符号所表示的数值表示该数字符号值乘以一个与数字符号有关的常数,该常数称为 “位权 ” 。位权的大小是以基数为底,数字符号所处的位置的序号为指数的整数次幂。十进制数的百位、十位、个位、十分位的权分别是10的2次方、10的1次方、10的0次方,10的-1次方。二进制数就是2的n次幂。按权展开求和正是非十进制化十进制的方法。下面我们开讲原理,举个十进制整数转换为二进制整数的例子,假设十进制整数A化得的二进制数为edcba 的形式,那么用上面的方法按权展开, 得A=a(2^0)+b(2^1)+c(2^2)+d(2^3)+e(2^4) (后面的和不正是化十进制的过程吗)假设该数未转化为二进制,除以基数2得A/2=a(2^0)/2+b(2^1)/2+c(2^2)/2+d(2^3)/2+e(2^4)/2注意:a除不开二,余下了!其他的绝对能除开,因为他们都包含2,而a乘的是1,他本身绝对不包含因数2,只能余下。商得:b(2^0)+c(2^1)+d(2^2)+e(2^3),再除以基数2余下了b,以此类推。当这个数不能再被2除时,先余掉的a位数在原数低,而后来的余数数位高,所以要把所有的余数反过来写。正好是edcba2.十进制小数转换为二进制小数十进制小数转换成二进制小数采用"乘2取整,顺序排列"法。具体做法是:用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,此时0或1为二进制的最后一位。或者达到所要求的精度为止。然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有效位。十进制小数转二进制如:0.625=(0.101)B0.625*2=1.25======取出整数部分10.25*2=0.5========取出整数部分00.5*2=1==========取出整数部分1再如:0.7=(0.1 0110 0110...)B0.7*2=1.4========取出整数部分10.4*2=0.8========取出整数部分00.8*2=1.6========取出整数部分10.6*2=1.2========取出整数部分10.2*2=0.4========取出整数部分00.4*2=0.8========取出整数部分00.8*2=1.6========取出整数部分10.6*2=1.2========取出整数部分10.2*2=0.4========取出整数部分0原理:关于十进制小数转换为二进制小数假设一十进制小数B化为了二进制小数0.ab的形式,同样按权展开,得B=a(2^-1)+b(2^-2)因为小数部分的位权是负次幂,所以我们只能乘2,得2B=a+b(2^-1)注意a变成了整数部分,我们取整数正好是取到了a,剩下的小数部分也如此。值得一提的是,小数部分的按权展开的数位顺数正好和整数部分相反,所以不必反向取余数了。
转载于:https://www.cnblogs.com/h-c-g/p/10093423.html
第六章递归
题目二借鉴自:
https://blog.csdn.net/u011954296/article/details/51029600
一.题目分析
题目一:将非负十进制整数n转换成b进制。(其中b=2~16)
这道题目要求将十进制分别转化为二进制、八进制和十六进制。递归函数重视寻找递归体和递归的终止条件。
题目二:任何一个正整数都可以用2的幂次方表示。例如:
137=27+23+20。同时约定方次用括号来表示,即ab可表示为a(b)。由此可知,137可表示为: 2(7)+2(3)+2(0)。进一步:7=22+2+20(21用2表示)3=2+20。所以最后137可表示为:
2(2(2)+2+2(0))+2(2+2(0))+2(0)。
先将输入数据137按指数从大到小分为2(7)+2(3)+2(0),然后又将指数按上面同样的方法分为2(2)+2+2(0)、2+2(0)、0,就可分出137的最终结果2(2(2)+2+2(0))+2(2+2(0))+2(0)。非常明显,这道题应该运用递归思想。
二.算法构造
题目一:
递归方法:递归体为ds(s / 2),递归终止条件为s0。其中s为输入的十进制数字。s%x,x为想转换的进制。当s0时,return。此外的情况,执行递归体。在十进制转换为二进制、十进制和十六进制问题上采取同样的方法。注意在十进制装换为十六进制时,若是s % 16 > 9),则需要执行printf("%c", s % 16) - 10 + ‘A’);。这是由于十六进制中09可以用自身表示,而1015需要用‘A’~‘F’表示。
非递归方法:输入十进制数s,s==0时,结束。其他情况执行s/x(x为想转换的进制),且输出s%x,执行此操作的条件为s!=0。所以要借助于do~while()语句。
题目二:如果输入fun(137,0),则输出为2(7)+2(3)+2(0)。 这时,如果对7和3递归处理,则为满足题意的输出。void fun(int n, int r),其中n为操作数,r为递归深度。
三.程序实现
题目一:#include<stdio.h> #include<windows.h> //递归实现十进制转换为二进制 int ds(int s) { //s = s / 2; //取模操作 //printf("%d", s % 2); //对/2获得的整数进行取余操作 if (s == 0) { return; } else { ds(s / 2); //递归体 printf("%d", s % 2); //对s取余操作 } } int main() { int d = 0; printf("请输入一个十进制数:"); scanf_s("%d", &d); ds(d); system("pause"); return 0; } //递归实现十进制转换为八进制 int ds(int s) { if (s==0) { return ; } else { ds(s / 8);//取模操作 printf("%d", s % 8); //对s进行取余操作 } } int main() { int d = 0; printf("请输入一个十进制数:"); scanf_s("%d", &d); ds(d); system("pause"); return 0; } //递归实现十进制转换为十六进制 int ds(int s) { if (s == 0) { return; } else { ds(s / 16); if (s % 16 > 9) //printf("%c", s % 16); printf("%c", (s % 16) - 10 + 'A'); else printf("%d", s % 16); //printf("%d", s % 16); } } int main() { int d = 0; printf("请输入一个十进制数:"); scanf_s("%d", &d); ds(d); system("pause"); return 0; } //非递归实现十进制转换为二进制 int main() { int s = 0; printf("请输入一个十进制数:"); scanf_s("%d", &s); if (s == 0) { return; } else do{ s = s / 2; printf("%d", s % 2); }while(s!=0);// 对s取余操作 system("pause"); return 0; } //非递归实现十进制转换为八进制 int main() { int s = 0; printf("请输入一个十进制数:"); scanf_s("%d", &s); if (s == 0) { return; } else do { s = s / 8; printf("%d", s % 8); } while (s != 0);// 对s取余操作 system("pause"); return 0; } //非递归实现十进制转换为十六进制 int main() { int s = 0; printf("请输入一个十进制数:"); scanf_s("%d", &s); if (s == 0) { return; } else do{ s = s / 16; if (s % 16 > 9) printf("%c", (s % 16) - 10 + 'A'); else printf("%d", s % 16); } while (s != 0); system("pause"); return 0; }
题目二:
void fun(int n, int r) { //递归结束,最先输出,不带+号 if (1 == n) { //将r表示成0和2 switch (r) { //2^0,递归深度为0 case 0: printf("2(0)"); break; //2^1,递归深度为1 case 1: printf("2"); break; //2^2,递归深度为2 case 2:printf("2(2)"); break; //2^r,递归深度为r default: printf("2("); fun(r, 0); printf(")"); } } else { //n除以二,递归深度加1 fun(n / 2, r + 1); //如果模2有余数,则为2^r if (1 == n % 2) { //将r表示成0和2 switch (r) { //2^0,递归深度为0 case 0:printf("+2(0)"); break; //2^1,递归深度为1 case 1:printf("+2"); break; //2^2,递归深度为2 case 2:printf("+2(2)"); break; //2^r,递归深度为r default: printf("+2("); fun(r, 0); printf(")"); } } } } int main() { fun(137, 0); system("pause"); return 0; } 此题借鉴自: https://blog.csdn.net/u011954296/article/details/51029600
四.调用过程
题目一:
上图为十进制转换为二进制的调用过程,十进制转换为八进制和十进制转换为十六进制的过程与上图方法相同。
五.运行结果
题目一:
十进制转化为二进制:
十进制转换为八进制:
十进制转换为十六进制:
题目二:
六.经验总结
在接触到题目一时,首先应该了解到数制之间该如何转换的细节。然后构思递归实现的具体细节。涉及递归处理问题时,必须要将大问题转换为小问题,最重要的是寻找递归终止条件和构造递归体。“除2取余,逆序输出”是十进制转换为二进制数的思想核心,其它进制的转换同理。。非递归实现题目一时,思路不变,对程序稍作改动,并且借助于do~while()语句即可。对于题目二余力不足呐。