C-Note: conversion problems between the binary number system (number system)

Original link: http://c.biancheng.net/view/1725.html

Brief introduction

Although the current computer operation quickly, but the data it uses internally is not as familiar to humans decimal number, but containing only the binary 1s and 0s. We decimal input into a computer to be converted into a binary number and then calculated, and the results calculated by the binary converted into decimal numbers we need, these are done automatically by the operating system, a number system with a fixed uniform rules and symbols to represent numerical methods, people usually have a number system decimal, binary, octal and hexadecimal.

The basic concept of the band

Binary, octal, hexadecimal difference between decimal, that:

  • Digital different ranges (the numbers on the individual bits) represented by binary digital 0 and 1, with a digital hexadecimal 0 ~ 9, A ~ F
  • Base (can be used as a digital number) is different from the binary base 2, base 16 hexadecimal
  • Right bit (bit weights on bit i of the base of the (i-1) th power, from left to right are No. 1, No. 2 ...), such as the right 1 bit decimal bit location 123 is 10 2,2 ^ where is the right 10-bit bit position where bit-1,3 ^ 10 ^ 0 weight; binary number 1101, a right of the leftmost 2 ^ 3

The difference between binary, octal, hexadecimal addition and subtraction

Binary

Thought binary and decimal subtraction addition and subtraction are similar: For binary, two o'clock when performed by a binary adder comes just one, the subtraction.

  • Binary addition: 1 + 0 = 1 + 1 = 10, 11 + 10 = 101, 111 + 111 = 1110
    Here Insert Picture Description
  • Binary Subtraction: 1-0 = 1,10-1 = 1,101-11 = 101 = 10,1100-111
    Here Insert Picture Description

Octal

0 to 7 octal digits 8, the base 8, into an addition operation comes just eight, when eight o'clock by a subtraction. For example, digital 0,1,5,7,14,733,67001,25430 are valid octal.

  • Octal addition: 3 + 4 = 7, 5 + 6 = 42 + 13.75 = 567 = 3216 + 137,2427

Here Insert Picture Description

  • Octal Subtraction: 6-4 = 2,52-27 = 23,307-141 = 5757 = 146,7430-1451
    Here Insert Picture Description

Hex

Hexadecimal, represented by A 10, B represents 11, C represents 12, D represents 13, E represents 14, F represents 15, and therefore have 0 ~ F 16 digits, base 16, an adder comes just 16 into 1, 1 when the subtraction by 16. For example, figures 0,1,6,9, A, D, F, 419, EA32,80A3, BC00 are valid hexadecimal.

  • Hex addition: 6 + 7 = D, 18 + BA = D2,595 + 792 = D27,2F87 + F8A = 3F11

Here Insert Picture Description

  • Subtraction Hex: D-3 = A, 52-2F = 23, E07-141 = CC6,7CA0-1CB1 = 5FEF

Here Insert Picture Description

Conversion between number system

Scenario 1, binary, octal, hexadecimal to decimal (Summary: by adding the right)

Binary, octal and hexadecimal to decimal conversion is very easy, is "by right (right position) are added." Students do not know the right place can look up.
Suppose the current number is N-ary, then:

  • 对于整数部分,从右往左看,第 i 位的位权等于Ni-1
  • 对于小数部分,恰好相反,要从左往右看,第 j 位的位权为N-j

整数部分(不带小数)

将二进制数字11010转换成十进制:

11010 = 1×2^4 + 1×2^3 + 0×2^2 + 1×2^1 + 0×2^0 = 26(十进制)

八进制数字 53627 转换成十进制:

53627 = 5×8^4 + 3×8^3 + 6×8^2 + 2×8^1 + 7×8^0 = 22423(十进制)

十六进制数字 9FA8C 转换成十进制(将A~F对应的具体的数字计算):

9FA8C = 9×16^4 + 15×16^3 + 10×16^2 + 8×16^1 + 12×16^0 = 653964(十进制)

整数部分+小数部分

二进制数字1010.1101 转换成十进制:

1010.1101 = 1×2^3 + 0×2^2 + 1×2^1 + 0×2^0 + 1×2^-1 + 1×2^-2 + 0×2^-3 + 1×2^-4 = 10.8125(十进制)

八进制数字 423.5176 转换成十进制:

423.5176 = 4×82 + 2×81 + 3×80 + 5×8-1 + 1×8-2 + 7×8-3 + 6×8-4 = 275.65576171875(十进制)

小数部分和整数部分相反,要从左往右看,第1位的位权为 8-1=1/8,第2位的位权为 8-2=1/64,第3位的位权为 8-3=1/512,第4位的位权为 8-4=1/4096 …… 第m位的位权就为 8-m。

C语言实现代码(仅讨论整数):

/*
将一个2,8进制转换为十进制 (算法思维从高位到低位运算,暂时没考虑16进制) 
*/
#include <stdio.h>
#include <string.h>//strlen()
int OcToDec(char *a,int base);//将2,8进制数a转换为十进制数 
int main(void)
{
 char a[20];//a存放八进制整数
 int tennum;//存放a对应的十进制整数
 printf("请输入一个数:") ;
 scanf("%s",a);//输入的时候,a[20]={1,0,1}  
 int n;
 printf("请输入该数的基数(输入的是几进制基数就是几):");
 scanf("%d",&n);
 tennum=OcToDec(a,n);
 printf("%d进制数%s转换为十进制为:%d\n",n,a,tennum);
 return 0;
}
int OcToDec(char *a,int base)
{
 int sum=0;//变量sum存放a对应的十进制数 
 int len=strlen(a);//位数 
 int weight=1;//位权值
 for(int i=len-1;i>=0;i--)//将八进制从低位向高位输出, 即数组a下标最大的元素为八进制的最低位 
 {
  sum+=(a[i]-'0')*weight;//数组下标i越小,即八进制位数越高,位权weight越重 ,a[i]-'0'转化为Ascii码运算到到一个字符数字对应的整型数字 
  weight*=base; 
 } 
 return sum;
}

测试输出:
Here Insert Picture Description
Here Insert Picture Description
扩展:以下代码块将int OcToDec(char *a,int base)函数体修改一下,让其从二进制或八进制高位向低位扫描各位上的数,按权相加求和。其中base为基数2或8

int OcToDec(char *a, int base)   //将base(8)进制数a转换成十进制数 
{
 int sum = 0;              
    int len = strlen(a);    
            
 for(int i = 0;i < len;i++)
 {  
     sum = sum * base + a[i] - '0';      
 }
 return sum;
}

情景二、将十进制转换为二进制、八进制、十六进制(总结:整数部分为除 N 取余,逆序排列,小数部分为乘 N 取整,顺序排列N为要转换对应进制的基数

将十进制转换为其它进制时比较复杂,整数部分和小数部分的算法不一样。如果一个数字既包含了整数部分又包含了小数部分,那么将整数部分和小数部分开,分别按照上面的方法完成转换,然后再合并在一起即可。

整数部分(不带小数)

具体做法:

  • 将 N (要转化的目标进制的基数) 作为除数,用十进制整数除以 N,可以得到一个商和余数;
  • 保留余数,用商继续除以 N,又得到一个新的商和余数;
  • 仍然保留余数,用商继续除以 N,还会得到一个新的商和余数;
  • 如此反复进行,每次都保留余数,用商接着除以 N,直到商为 0 时为止。

将十进制数字 36926 转换成八进制:
Here Insert Picture Description
结果为110076(八进制)。

将十进制数字 42 转换成二进制的过程:
Here Insert Picture Description

结果为101010(二进制)

整数部分+小数部分

具体做法:

  • 用 N(要转化的目标进制的基数) 乘以十进制小数,可以得到一个积,这个积包含了整数部分和小数部分;
  • 将积的整数部分取出,再用 N 乘以余下的小数部分,又得到一个新的积;
  • 再将积的整数部分取出,继续用 N 乘以余下的小数部分;
  • 如此反复进行,每次都取出整数部分,用 N 接着乘以小数部分,直到积中的小数部分为 0,或者达到所要求的精度为止。

十进制小数 0.930908203125 转换成八进制小数的过程:
Here Insert Picture Description
十进制小数 0.930908203125 转换成八进制小数的结果为 0.7345。

十进制小数 0.6875 转换成二进制小数的过程:
Here Insert Picture Description
十进制小数 0.6875 转换成二进制小数的结果为 0.1011。

C语言实现代码(仅讨论整数):

/*
将十进制转换为2,8,16进制 
*/
#include <stdio.h>
#include <string.h>
void DToM(int d,int m,char *mnum);//D->decimalism 
int main(void)
{
 int d;//存放输入的十进制数
 printf("请输入一个待转换的十进制数:"); 
 scanf("%d",&d);
 int M;
 printf("请输入要转换的进制(2,8,16):");
 scanf("%d",&M);
 char Mnum[100];//存放十进制数d对应的M进制数
 DToM(d,M,Mnum);
 printf("该十进制数对应的%d进制数为:%s\n",M,Mnum); 
 return 0;
}
void DToM(int d,int m,char *mnum)//d为十进制数,m为要转换的目标进制数,mnum指向的数组存放转换结果 
{
 int len=0,r=0;//存放mnum指向数组的下标以及余数 
 do
 {//除M取余 
  r=d%m;
  if(r >= 10) //针对要转换为16进制的情况 
         mnum[len++] = r - 10 + 'A';   //将对应的整数转换成字母字符
     else      
         mnum[len++] = r + '0';     //将对应的整数转换成数字字符
  d/=m;
 }while(d!=0);
 mnum[len]='\0';
 char t;
 for(int i=0,j=len-1;i<j;i++,j--)//逆置输出 
 {
  t=mnum[i];
  mnum[i]=mnum[j];
  mnum[j]=t;
 }
}

测试输出:
Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

情景三、二进制和八进制、十六进制的转换(总结:通常二进制的3位分别用八进制的3位和十六进制的4位来表示)

首先可以使用上面的方法

  • 将二进制转换为十进制(对应上文讲到的情景一),然后十进制转换为对应的的八进制和十六进制(对应上文讲到的情景二)
  • 亦或者将八进制和十六进制转换为十进制(情景一),然后十进制转化为二进制(情景二)

C语言实现代码(将情景一和情景二的代码整合一下,即借助十进制数作为中介):

/*
N进制到M进制 
*/ 
#include <stdio.h>
#include <string.h>
int NToD(char *a,int base);//将N进制数a转换为十进制数 (N可以考虑二、八、十六进制)
void DToM(int d,int m,char *mnum);//再将十进制转换成M进制(M可以考虑二,八,十六进制)
int getIndexOfSigns(char *ch);//NtoD函数内调用
int main(void)
{
 int N,M;//要将N进制数转换成M进制数 
 char Nnum[20],Mnum[20];//存放N进制数以及转换后的M进制数
 printf("要将N进制数Nnum转换成M进制数请输入以下格式\nN Nnum M:"); 
 scanf("%d %s %d",&N,Nnum,&M);
 int d=NToD(Nnum,N);//将N进制数Nnum转换成十进制数d
 DToM(d,M,Mnum);//将十进制数d转换成M进制数Mnum
 printf("%d进制数%s转换成%d进制数为:%s\n",N,Nnum,M,Mnum); 
 return 0; 
}
int NToD(char *a,int base)
{
 int sum=0;//变量sum存放a对应的十进制数 
 int len=strlen(a);//位数 
 int weight=1;//位权值
 for(int i=len-1;i>=0;i--)//将N进制从低位向高位输出, 即数组a下标最大的元素为八进制的最低位 
 {
  sum+=(getIndexOfSigns(a[i]))*weight;//数组下标i越小,即八进制位数越高,位权weight越重 ,a[i]-'0'将字母映射为十进制数 
  weight*=base; 
 } 
 return sum;
}
void DToM(int d,int m,char *mnum)
{
 int len=0,r=0;//存放mnum指向数组的下标以及余数 
 do
 {//除M取余 
  r=d%m;
  if(r >= 10) //针对要转换为16进制的情况 
         mnum[len++] = r - 10 + 'A';   //将对应的整数转换成字母字符
     else      
         mnum[len++] = r + '0';     //将对应的整数转换成数字字符
  d/=m;
 }while(d!=0);
 mnum[len]='\0';
 char t;
 for(int i=0,j=len-1;i<j;i++,j--)//逆置输出 
 {
  t=mnum[i];
  mnum[i]=mnum[j];
  mnum[j]=t;
 }
}
int getIndexOfSigns(char *ch)
{
    if(ch >= '0' && ch <= '9')
    {
        return ch - '0';
    }
    if(ch >= 'A' && ch <='F') 
    {
        return ch - 'A' + 10;
    }
    if(ch >= 'a' && ch <= 'f')
    {
        return ch - 'a' + 10;
    }
    return -1;
}

情况三代码是对情况一和情况二的综合,将情况一的int OcToDec()改了一下见名知意的名字int NToD(),内部代码块没改,然后直接使用情况二的void DToM(),然后多加了一个int getIndexOfSigns(char *ch)增加了情况一对16进制的支持。

Test output (in a case in which the function is improved, support hexadecimal to decimal conversion):
Here Insert Picture Description
Here Insert Picture Description

Here uses a simple approach:

Integer conversion between binary and octal integer

When binary integer octal integer, each three-digit binary number is converted to an octal numbers (due to the binary number can only be a maximum of 3 7, and octal digital precisely 0 to 7,3-bit binary bits are added by right to obtain a decimal number), the order of operations is sequentially performed from the low-order bit, three zero-padded insufficient high, the final spliced ​​together.

Binary integer 1110111100 to octal result of 1674:

Here Insert Picture Description
The result is 1674 (octal)

When octal integer into a binary integer, is the opposite of the idea that every three octal number is converted to a binary digit, is the order of operations carried out in order from low to high. The following illustration shows how to convert 2743 octal binary integer:
Here Insert Picture Description
result 010 111 100 011 (binary)

Integer conversion between binary and hexadecimal integer

When the binary integer to hexadecimal integers, each four binary number is converted to a hexadecimal number, order of operations is carried out sequentially from low to high, less than four high padded with zeros. The following illustration shows how the binary integer 10,110,101,011,100 convert to hex:
Here Insert Picture Description
binary integer 10,110,101,011,100 converted to hexadecimal result 2D5C (Note: decimal Yaoan corresponding hexadecimal representation notation).

When hexadecimal integer into a binary integer, is the opposite of the idea that every four hexadecimal number is converted to a binary digit, is the order of operations carried out in order from low to high. The following illustration shows how to convert a hexadecimal integer A5D6 to binary:

Here Insert Picture Description
As can be seen from the figure, the result is converted into a binary hexadecimal integer A5D6 is 1,010,010,111,010,110.

Guess you like

Origin blog.csdn.net/weixin_42124234/article/details/101616137