一、各种进制(整数部分)的相互转换
1.1: 二进制、八进制、十进制、十六进制均是数值的不同表示形式
补充:各种进制数在变量(内存)中存储的值
int main()
{
int a = 0B11111111111111111111111111111111;
//a在内存中存储的补码:11111111111111111111111111111111
int b = 0xffffffff;
//0xffffffff转换成二进制是11111111111111111111111111111111,b在内存中存储的补码:11111111111111111111111111111111
int c = -1;
//-1的原码:10000000000000000000000000000001
//-1的补码:11111111111111111111111111111111
//则c在内存中存储的补码:11111111111111111111111111111111
printf("%d %d %d", a,b,c);//-1 -1 -1
return 0;
}
①2进制的数是由0、1组成 ; 8进制的数是由0到7组成
②10进制的数是由0到9组成 ;16进制的数是由0到9,以及a到f组成。(a表示10,f表示15)
③8进制数字每⼀位是 0到7 之间的数,0~7 的数字,各自写成2进制,最多有3个2进制位就足够了。因此一个八进制位可以用3个二进制位表示。16进制的数字每⼀位是0到9,与a到f之间的数 ,0到9,与a到f之间的数 ,各自写成2进制,最多有4个2进制位就足够了。因此一个16进制位可以用4个二进制位表示。
1.2:10进制是满10进1,2进制是满2进1,依此类推可知n进制是满n进1
1.3:各种进制转十进制
a. 二进制转十进制
b.八进制转十进制
c.十六进制转十进制
1.4:各种进制转二进制
a.十进制转二进制
不断除以2取余数,除到商为0为止,余数倒着排
b.八进制转二进制
从右往左,每1个八进制位转换为3个二进制位。原理:3个二进制位可以表示1个八进制位
c.十六进制转二进制
从右往左,每一个16进制位转换为4个二进制位。原理:4个二进制位可以表示1个十六进制位
1.5:二进制转八进制
从右往左,每3个二进制位转化为一个八进制位,剩余不够3个二进制位的之间转换。
转换原理:每一个八进制位可以用3个二进制位表示。
1.6:二进制转十六进制
从右往左,每4个二进制位转换为1个二进制位,剩余不够4个二进制位的直接转换
转换原理:16进制的每一位(0到9以及a到f),每一个16进制位可以用4个二进制位就可以表示。
1.7:其他进制之间该如何转换?
比如如何将8进制转换为16进制?
可以先将8进制转换为2进制,再将2进制转换为16进制
二、操作符的分类
三、原码、反码、补码
①整数的2进制表示方法有三种,即原码、反码和补码。
a.有符号整数的原、反、补码是由符号位与数值位组成,二进制序列的最高位是符号位(用0表示正数,1表示负数),其余位是数值位。无符号整数的原、反、补码的每一位都是数值位
②0与正整数的原、反、补码相同,且0的原、反、补码是全0,负整数的原、反、补码各不相同,-1的补码是全1
③原、反、补码之间的相互转换
a.原码:直接将数值按照正负数的形式 (若是正数,最高位是0,;若是负数,最高位是1),翻译成二进制序列得到的就是原码。
b.反码:在原码的基础上,符号位不变,其余位逐位取反。
c.补码:反码加1就是补码。
总结:原码到补码、补码到原码,都是遵循取反加1的原则。其中取反是指符号位不变取余位逐位取反。
int main()
{
int a = -1;
/*
-1是负整数,原、反、补码各不相同
-1的原码:10000000000000000000000000000001
-1的反码:11111111111111111111111111111110
-1的补码:11111111111111111111111111111111
*/
int b = 1;
//1是正整数,原、反、补码相同,即00000000000000000000000000000001
return 0;
}
④整数在内存中存储的是补码
⑤在计算机中,整数之间的各种运算(加减乘除等)都是采用补码运算
举例:计算机是怎么计算1-1的呢?
计算机的cpu中只有加法器,会将减法转换为加法,即计算1+(-1)
/*
假设一个整型采用32个比特位来存储
若采用原码进行计算
1的原码: 00000000000000000000000000000001
-1的原码: 10000000000000000000000000000001
1的原码加-1的原码: 10000000000000000000000000000010 :表示的是-2
显然采用原码计算是不对的
若采用补码计算
1的补码: 00000000000000000000000000000001
-1的补码: 11111111111111111111111111111111
1+(-1)的补码:100000000000000000000000000000000
由于一个整型采用的是32个比特位存储,因此1+(-1)的补码中的最高位被丢弃了
即1+(-1)的补码变成了00000000000000000000000000000000 (0的补码是全0)
故1+(-1)的结果是0
*/
⑥一个字节能存储的有符号整数的取值范围(-128 ~ 127),比如signed char类型的数据
/*
有符号整数的原、反、补码是由符号位与数值位组成
十进制 原码 反码 补码
127 01111111 01111111 01111111
126 01111110 01111110 01111110
...... ........ ........ ........
3 00000011 00000011 00000011
2 00000010 00000010 00000010
1 00000001 00000001 00000001
0 00000000 00000000 00000000
-1 10000001 11111110 11111111
-2 10000010 11111101 11111110
-3 10000011 11111100 11111101
...... ........ ........ ........
-126 11111110 10000001 10000010
-127 11111111 10000000 10000001
在补码的二进制序列中还差10000000
00000000 01111111 10000000
可以看出,当补码是10000000时,对应的原码是00000000,原码被解析成十进制时应该是0
但当补码是00000000时,对应的原码也是00000000,原码被解析成十进制也是0
二者造成了冲突,于是C语言中规定,补码10000000被解析成有符号整数时的值是-128
*/
⑥一个字节能存储的无符号整数的取值范围是(0 ~ 255),比如unsigned char类型的数据