一、为什么使用二进制、八进制、十六进制?
1.1 二进制
目前的CPU只能识别高低两种电平,只能对二进制数据进行计算
1.2 八进制
二进制虽然能够直接被计算机识别,但是不方便人去书写和记录,因此就把二进制转换为八进制,方便记录到文档中
1.3 十六进制
随着CPU位数的不断增加,已经到目前的64位,所以八进制不再能够满足需求,因此发展出现在的十六进制,由于历史原因八进制还不能退出历史舞台
二、十进制转二进制
2.1 求余法(十进制转其他进制也适用)
用2不停对数据求余,然后继续对商求余,直到商为0结束,在过程中得到的余数逆序就是该数据的二进制。
例如:127的转为二进制为1111111
转换过程:
127 % 2 = 63···1
63 % 2 = 31···1
31 % 2 = 15···1
15 % 2 = 7··· 1
7 % 2 = 3··· 1
3 % 2 = 1··· 1
1 % 2 = 0··· 1
补充:用代码实现求余法:正整数m转成n(n>2)进制
#include <stdio.h>
int main()
{
int m,n,i=0;
char arr[32]={};
scanf("%d%d",&m,&n);
while(m)
{
arr[i]=m%n;
i++;
m=m/n;
}
for(int j=i-1;j>=0;j--)
{
if(arr[j]>9)
{
printf("%c",arr[j]+55);
}
else
{
printf("%hhd",arr[j]);
}
}
}
2.2 求权法
数据从高位n位开始,数据 - 2^(n-1),如果够减,则第n位为1,否则为0,直到减完为止。
例如:
权值
数值
128 64 32 16 8 4 2 1 134 1 0 0 0 0 1 1 0 73 1 0 0 1 0 0 1 62 1 1 1 1 1 0 121 1 1 1 1 0 0 1 49 1 1 0 0 0 1
三、二进制转十进制
每位乘以权位2^(n-1),求和
四、二进制转八进制
从低位起每三个二进制位对应一个八进制位
例如:二进制 10 101 110 111 101
八进制 2 5 6 7 4
五、二进制转16进制
从低位起每四个二进制位对应一个16进制位
例如:二进制 10 1011 1011 1100
16进制 2 B B C
六、不同进制在程序中显示
在C代码中,以0开头的数据是八进制数据,
以0x/0X开头的是16进制,没有二进制表示方式。
%x 让数据以16进制显示
%o 让数据以八进制显示
%#x %#o 显示出数据对应的前缀
例如:
>> printf("%x",0x123)
>> 0x123
七、原码反码补码
7.1 原码
数据的二进制,最高位符号位(最高位和数据类型有关,例如int32位,char8位) 1为负,0为正
7.2 反码
正数的原码就是反码
负数的反码:它的原码符号位不变,其他位按位求反
7.3 补码
① 所有数据在计算机中都是以补码形式存储
② 正数的原码就是补码
③ 负数的补码:
a. 先转成二进制得到原码,
b. 原码符号位不变,其余按位求反,得到反码,
c. 反码+1,得到补码
④ 补码转成数据:
a. 先确定有符号还是无符号
b. 如果是无符号\有符号最高位为0,直接转成十进制
c. 如果是有符号且最高位为1
>> 补码-1=反码;
>> 符号位不变,其余位按位求反,得到原码;
>> 原码转十进制。
八、位运算符
8.1 A & B 按位相与
1010 1110 A 0xAE
0111 1100 B 0x7C
--------------------
0010 1100 C 0x2C
8.2 A | B 按位相或
1010 1110 A 0xAE
0111 1100 B 0x7C
-------------------
1111 1110 C
8.3 ~A 按位求反
1010 1110 A 0xAE
-------------------
0101 0001
8.4 A ^ B 按位异或 相同为零,相异为一
1010 1110 A 0xAE
0111 1100 B 0x7C
-------------------
1101 0010
8.5 A << n 按位左移n位,左边超出的丢弃,右边补0
1010 1110 A << 3
------------------
0111 0000
8.6 A >> n 按位右移n位,右边超出的丢弃,左边补符号位
1010 1110 A >> 3
------------------
1111 0101