操作符有很多种,这篇文章我会向大家详细介绍与二进制相关的移位操作符和位操作符。
首先,我会介绍二进制和进制转换的相关知识;其次,会详细说明原码,反码,补码;最后,叙述移位操作符和位操作符的知识。
一.二进制和进制转换
我们经常可以听到2进制,8进制,10进制,16进制这种说法,其实它们只是数值的不同表示形式而已。
例如:数值15的各种表示形式
1.二进制
我们从10进制讲起,10进制中满10进1,10进制每一位都是0-9的数字。二进制也类似,它满2进1,2进制每一位都是0-1的数字。
我们用2进制数1111分析2进制转10进制
2.10进制转化为2进制
采用除以2取余的方法。对10进制数反复除二取余数,直到商为0或1,然后把每次得到的余数倒着排列,就是转换后的2进制数。
以34为例
3.2进制转8进制
8进制每一位都是0-7的数字,每个数字写成2进制的,有三个2进制数就够了,比如7的2进制是111。所以在2进制转换8进制时,从低位到高位(从右往左),每3个2进制位会换算成一个8进制位,剩余不够3个2进制位的直接换算。8进制转换为2进制反向操作就可以。
例:2进制的11101010转换为8进制0352.
4.2进制转16进制
16进制每一位都是0-9和a-f,(a-f对应着10-15),每个写成2进制数,最多4位就够了,比如f的2进制是1111。所以在2进制转16进制时,从低位到高位(从右往左),每4个2进制换算成一个16进制位,剩余不够的直接换算。16进制换2进制反向操作。
例:2进制的01111100转换为16进制0x7c.
二.原码、反码、补码
整数的2进制表示方法有3种,原码、反码、补码。
有符号数是既能表示负数又能表示正数的数,2进制序列中,它分为符号位(最高的一位为符号位,用0表示正,用1表示负)和数值位(除去符号位剩余的为数值位)。
(1)原码:直接将数值按照正负数的形式转换为2进制得到的数。
(2)反码:原码符号位不变,其他数依次取反得到反码。
(3)补码:反码+1得到补码。
举个例子:
补码转换为原码有两种途径:一是可以补码-1再取反,二是补码取反再+1(推荐这个,刚好和原码转补码路径一样)。
对于正数,原码、反码、补码都相同。
对于负数,原码、反码、补码的符号位都为1,原码其他数就是此数绝对值的2进制,反码其他位是原码取反,补码是反码+1 。
在计算机中,对于任意的二进制,都是使用补码来表示和储存。是因为使用补码,可以将符号位和数值位一同处理,而且在计算机中,实际上只有加法运算(减法会转换为加法),都可以统一处理。补码和原码转换路径相同,简化了运算规则和运算器的电路。
三.移位操作符 (操作数只能是整数)
1.左移操作符 <<
移位规则:左边丢弃,右边补0
用两个例子(正数,负数)让大家更好地理解
要注意的是原来那个数的值并不会改变。
2.右移操作符 >>
移位规则(取决于编译器):
1.逻辑右移:右边丢弃,左边补0
2.算术右移:右边丢弃,左边用原来此数值的符号位补齐(常见的编译器都采用算术右移,如VS,gcc等)
举两个例子(正数,负数):
注意:移位操作符不能移动负数位,标准未定义。例如:
四.位操作符(操作数只能是整数)
注意:计算机中计算用的都是补码,而由于正整数原码与补码相同,我们会有一种只用原码计算的错觉。负数的原码与补码不同。
1.按位与 &
运算规则:两个整数的2进制数对应比较,两个都为1则是1,其他都为0.
计算机计算和内存中都是补码,打印的是原码。
举例:4&(-7)
2.按位或 |
运算规则:两个整数对应2进制对应,有1则为1,两个都为0才为0
举例:4|(-7)
3.按位异或 ^
运算规则:补码进行按位异或,相同为0,相异为1.
举例:4^(-7)
按位异或的性质
(1)任何数和自己异或结果为0。a^a=0
(2)任何数和0做异或运算,结果仍是原来的数。a^0=a
(3)按位异或自反性,两次运算操作,可以将最后结果还原。
(4)交换律和结合律。a^b^c=a^c^b
4. 按位取反 ~
运算规则:补码1变成0,0变成1,符号位也参与运算
举例:~0
五.例题
不创建第三变量,进行变量a,b的数值交换
方法一:
这种方法有缺陷,int定义的数只占四个字节,若是a、b的值很大,那加起来可能会超出最大范围(溢出),导致数据丢失。
方法二:
熟练掌握按位异或的性质,这种方法简单、高效。
最后,大家有什么问题和建议都可以提出来,我们一起进步。