【説明する】进制转换
进制转换
1.计算机中采用二进制,因为二进制具有运算简单,易实现且可靠,为逻辑设计提供有利途径、节省设备等优点,为了便于描述,又长用八、十六进制作为二进制的缩写,一般技术都采用进位计数,其特点:
(1)逢N进一,N是每种进位计数制表示一位数所需要符号数目为基数。
二进制:逢二进一,借一当二
八进制:逢八进一,借一当八
十六进制:。。。。。。。。
(2)数制转换 不同进位计数制之间的转换原则:不同进位计数制之间的转换是根据两个有理数如相等,则两数的整数和分数部分一定分别相等的原则进行的,若转换前两数相等,转换后仍必须相等。
十进制:有十个基数:0,1,2,3,4,5,6,7,8,9
二进制:有两个基数:0,1
八进制:有八个基数;0,1,2,3,4,5,6,7
十六进制:有十六个基数:0—9,A,B,C,D,E,F(A=10,B=11,C=12,D=13,E=14,F=15)
一、十进制与其他进制之间的转换
1)十进制—二进制
十进制除以2,除至0时所得余数按反方向写出,即为二进制数
例:36除以2得出的商依次是 18 9 4 2 1
所得余数依次为 0 0 1 0 0 1
将余数从右往左写 1 0 0 1 0 0
所得出100100为二进制数
小技巧:为方便可将公式变为以下形式:
二进制 右数位数 |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
十进制数 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 |
公式原型 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
2)二进制—十进制
计算公式:a*20+b*21+c*22+....+m*2(n-1)=
以上公式,a表示二进制数的右边第一位的数,b表示二进制数的右边第二位的数,c表示二进制数的右边第三位的数.....m表示二进制数的右边第(n-1)位的数
例:1011001由右至左成为十进制为89
1*20+0*21+0*22+1*23+1*24+0*25+1*26
=1+8+16+64
=89
二、1)十进制—八进制
从右第n位 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 |
8(n-1) | 87 | 86 | 85 | 84 | 83 | 82 | 81 | 80 |
十进制下的实际数 | 2097152 | 262144 | 32768 | 4096 | 512 | 64 | 8 | 1 |
(2)同二进制转十进制
计算公式 a*80+b*81+c*82+d*83+.....+m*8(n-1)=
以上公式中,a表示八进制数的右边第一位的数,b表示八进制数的右边第二位的数,c表示八进制数的右边第三位的数.....m表示八进制数的右边第(n-1)位的数。
例:2137由右至左成为十进制为1119
7*80+3*81+1*82+2*83
=7+24+64+1024
=1119
三、1)十进制—十六进制
十进制数除以十六
0,1,2,3,4,5,6,7,8,9,A(10),B(11),C(12),D(13),E(14),F(15)
十进制数逐次整除16,至商为0,所得余数按相反顺序写出,即为其十六进制数。
例:75除以16得出的余数为11(B) 4
余数从右向左写为 4B
2)十六进制—十进制
同二进制、八进制一样
计算公式: a*160+b*161+c*162+d*163+.....+m*16(n-1)=
以上公式中,a表示十六进制数的右边第一位的数,b表示十六进制数的右边第二位的数,c表示十六进制数的右边第三位的数.....m表示十六进制数的右边第(n-1)位的数。
163 | 162 | 161 | 160 |
4096 | 256 | 16 | 1 |
例:1BC2由右至左成为十进制为7106
2*160+12*161+11*162+1*161
=2+192=2816+4096
=7106
四、其他进制之间的转换
二进制转换为八进制:对于整数,采用从右到左每三组一组,不够三位数的在其左边补齐0,每组单独转换出来,即为八进制数。
例:(001 101 111 011)
1 5 7 3
所以,(1573)即为所得八进制数。
八进制转换为二进制:将每位八进制由三位二进制数代替,即可完成转换。
例:(1 7 3 5)
001 111 011 101
所以,(1111011101)即为所得二进制数。
二进制转换为十六进制:由于2的4次方+16,所以依照二进制与八进制的转换方法,将二进制数的每四位用一个十六进制数码来表示,整数部分以小数点为界点从右往左每四位一组转换,小数部分从小数点开始自左向右每四位一组进行转换。
例 : (1001 0111 0111 1001)
9 7 7 9
所以,(9779)为所得的十六进制数
十六进制转换为二进制:只要将每一位十六进制数用四位相应的二进制数表示,即可完成转换。
例 : (8 7 6 5)
1000 0111 0110 0101
所以,(1000 0111 0110 0101)便为所得的二进制数。
来段伪代码:
while(该数!=0) {///若还能够继续分 int chu(除数)=该数/进制数,yu(余数)=该数-进制数*chu(除数); ///ans数组进行存储答案 ans[++cnt]=yu(余数); 该数=chu(除数); }
说完正数的处理,然后就是负数啦~
其实原理跟负数一模一样,只不过有一点点小不同!就是负数模负数的时候,计算机会出来负数,但我们知道,应该是正数!
经过大量实验证明:整数取模后是正整数取模的相反数
所以我们就可以轻松的使用小学学过的知识来解决这道题啦~
来一段伪代码:
while(该数!=0) {///若还能够继续分 int chu(除数)=该数/进制数,yu(余数)=该数-进制数*chu(除数); ///注:负整数取模后是正整数取模的相反数 if(yu(余数)<0) chu(除数)++; ///所以在这里用小学(maybe)的知识进行取反 ///ans数组进行存储答案 ///不能直接用yu更新的原因是若yu为负数, ///此时已经进行了改变,所以用除数更新 ans[++cnt]=该数-进制数*chu(除数); 该数=chu(除数); }
是不是跟正数的处理差不多呢!!?
没错!!!
over!!!
再来几道良心练手题~~~
将十进制数n转换成m进制数 m<=16
n<=100
共一行
n和m
共一个数
表示n的m进制
样例1:10 2
样例2:100 15
样例1:1010
样例2:6A
用反向取余法
分类标签 Tags 点此展开
1 #include <cstdio> 2 #include <iostream> 3 4 using namespace std; 5 6 int x[100]; 7 8 int jzzh(int y,int ml) 9 { 10 int i,a; 11 i=ml; //i表示要进行处理的数 12 x[0]=0; //进行计数 13 for(a=1;;a++) 14 { 15 if(i!=0) 16 { 17 x[a]=i%y; 18 x[0]++; 19 } 20 else 21 break; 22 i=i/y; 23 } 24 return x[0]; 25 } 26 int main() 27 { 28 int y,ml,a; 29 30 /* start 输入十进制数字的处理 */ 31 scanf("%d",&ml); 32 /* end 输入十进制数字的处理 */ 33 34 /* start 输入转换的进制处理 */ 35 do 36 { 37 scanf("%d",&y);//转换成几进制的数 38 }while(y<=0 || y>16); 39 /* end 输入转换的进制处理 */ 40 41 /* start 实际的进制转换 */ 42 jzzh(y,ml);//函数 43 /* end 实际的进制转换 */ 44 45 /* start 转换之后的数字输出 */ 46 for(a=x[0];a>=1;a--)//逆序输出 47 { 48 if(x[a]>=10)//ABCDEF的处理 49 { 50 printf("%c",x[a]+55); 51 } 52 else 53 { 54 printf("%d",x[a]); 55 } 56 } 57 //printf("\n");//换行 58 /* end 转换之后的数字输出 */ 59 60 return 0; 61 }
将m进制数n转化成一个十进制数 m<=16
题目保证转换后的十进制数<=100
共一行
n和m
共一个数
表示m进制的n化成十进制的数
1010 2
10
乘权累加法
分类标签 Tags 点此展开
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 7 using namespace std; 8 9 char s[111]; 10 int jz; 11 12 void zh(char* star,int jinzhi) 13 { 14 int len=strlen(star);//有多少位数(从零开始计数) 15 int num=1,sum=0; 16 for(int i=len-1;i>=0;i--) 17 { 18 if(s[i]-'0'<10)//如果该位数是数字 19 sum+=(s[i]-'0')*num;// 直接加上 20 else 21 { 22 switch(s[i])//其他的进行多进制的处理 23 { 24 case 'A': 25 s[i]=10; 26 break; 27 case 'B': 28 s[i]=11; 29 break; 30 case 'C': 31 s[i]=12; 32 break; 33 case 'D': 34 s[i]=13; 35 break; 36 case 'E': 37 s[i]=14; 38 break; 39 case 'F': 40 s[i]=15; 41 break; 42 } 43 sum+=s[i]*num; 44 } 45 num*=jinzhi; 46 } 47 printf("%d\n",sum); 48 } 49 50 int main() 51 { 52 cin>>s>>jz; 53 zh(s,jz); 54 return 0; 55 }
3.cogs86. [NOIP2000] 进制转换(综合哦~~~)
★ 输入文件:fjz.in
输出文件:fjz.out
简单对比
时间限制:1 s 内存限制:128 MB
描述 Description
我们可以用这样的方式来表示一个十进制数:将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以10为底数的幂之和的形式。例如,123可表示为1*10^2+2*10^1+3*10^0这样的形式。
与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置的(值-1)为指数,以2为底数的幂之和的形式。一般说来,任何一个正整 数R或一个负整数-R都可以被选来作为一个数制系统的基数。如果是以R或-R为基数,则需要用到的数码为0,1,....R-1。例如,当R=7时,所需 用到的数码是0,1,2, 3,4,5和6,这与其是R或-R无关。如果作为基数的数绝对值超过10,则为了表示这些数码,通常使用英文字母来表示那些大于9的数码。例如对16进制 数来说,用A表示10,用B表示11,用C表示12,用D表示13,用E表示14,用F表示15。在负进制数中是用-R作为基数,例如-15(+进制)相 当于110001(-2进制),
并且它可以被表示为2的幂级数的和数:
110001=1*(-2)^5+1*(-2)^4+0*(-2)^3+0*(-2)^2+0*(-2)^1+1*(-2)^0
问题求解:
设计一个程序,读入一个十进制数和一个负进制数的基数,并将此十进制数转换为此负进制下的数:-R∈{-2,-3,-4,....-20}
输入格式 Input Format
输入文件有若干行,每行有两个输入数据。
第一个是十进制数N(-32768<=N<=32767); 第二个是负进制数的基数-R。
输出格式 Output Format
输出此负进制数及其基数,若此基数超过10,则参照16进制的方式处理。【具体请参考样例】
样例输入 Sample Input
30000 -2
-20000 -7
28800 -16
-25000 -16
样例输出 Sample Output
30000=11011010101110000(base -2)
-20000=263526(base -7)
28800=19180(base -16)
-25000=7FB8(base -16)
UPD: 最后一组数据已由 Rapiz 修复。20161014
思路:
如我们上面所讲!!!裸的进制转换(进制转换有不是裸的的吗???!!!orz)
坑点:
最后一个点的10进制数为0,需要进行特判一下
上代码(这次就不折叠啦~~~):
#include <iostream> #include <cstring> #include <string> #include <cstdio> using namespace std; int ans[100000],w; void work(int jz,int ml) { int i=ml; while(i!=0) { int chu=i/jz,yu=i%jz; ///yu等价于 ↓ // int yu=i-jz*chu; ///注:负整数取模后是正整数取模的相反数 if(yu<0) chu++; ///所以在这里用小学(maybe)的知识进行取反 w++; ans[w]=i-jz*chu; // w++; i=chu; } // w--; printf("%d=",ml); for(int i=w;i>=1;i--) { ///更加方便的输出大写字母 if(ans[i]>=10) printf("%c",ans[i]+55); else printf("%d",ans[i]); } ///坑人的数据///加个特判orz if(ml==0) printf("0"); printf("(base%d)",jz); } int main() { freopen("fjz.in","r",stdin); freopen("fjz.out","w",stdout); int ml,jz; scanf("%d%d",&ml,&jz); work(jz,ml); return 0; }