zoukankan      html  css  js  c++  java
  • 【説明する】进制转换

    进制转换

    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!!!


     再来几道良心练手题~~~

    1.codevs1474 十进制转m进制
     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 白银 Silver
     
    题目描述 Description

    将十进制数n转换成m进制数 m<=16

    n<=100

    输入描述 Input Description

    共一行

    n和m

    输出描述 Output Description

    共一个数

    表示n的m进制

    样例输入 Sample Input

    样例1:10 2

    样例2:100 15

    样例输出 Sample Output

    样例1:1010

    样例2:6A

    数据范围及提示 Data Size & Hint

    用反向取余法

    分类标签 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("
    ");//换行 
    58     /* end 转换之后的数字输出 */
    59 
    60     return 0;
    61 }
    10进制转m进制
    2.codevs1475 m进制转十进制 
    时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 白银 Silver
     
    题目描述 Description

    将m进制数n转化成一个十进制数 m<=16

    题目保证转换后的十进制数<=100

    输入描述 Input Description

    共一行

    n和m

    输出描述 Output Description

    共一个数

    表示m进制的n化成十进制的数

    样例输入 Sample Input

    1010 2

    样例输出 Sample Output

    10

    数据范围及提示 Data Size & Hint

    乘权累加法

    分类标签 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
    ",sum);
    48 }
    49 
    50 int main()
    51 {
    52     cin>>s>>jz;
    53     zh(s,jz);
    54     return 0;
    55 }
    m进制转10进制

    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;
    }

    如果运气好也是错,那我倒愿意错上加错!

    ❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀

  • 相关阅读:
    jdk的entity表格注解·
    事务管理简单
    spring注解和jdk注解简单概述
    ssh框架简化
    spring简单的框架
    hibernate简单的框架
    struts2简单的框架
    ssh框架总结
    博客搬迁到新址
    动态编译和静态编译,共享库
  • 原文地址:https://www.cnblogs.com/zxqxwnngztxx/p/6746967.html
Copyright © 2011-2022 走看看