首先在了解位运算之前要先知道原码,反码,补码的概念,而在谈原码,反码,补码之前要知道什么是机器数,以及机器数的真值
目录
什么是机器数?
机器数是将符号“数字化”的数,是数字在计算机中的二进制表示形式
有两个特点:
1.符号数字化
2.其数的大小受机器字长的限制
计算机中机器数的最高位是符号位,正数符号位为0,负数为1
机器数的真值:
因为机器数带符号,故机器数的形式值不等于真正的数值,如:1000 0011表示-1而不是131
OK,那么接下来就可以认识什么是原码了。
原码:
原码就是加了符号位的二进制数,8位原码二进制数的大小范围为[1111 1111, 0111 1111],也就是[-127, 127]
反码:
正数的反码就是其原码本身,负数则是在其原码的基础上,符号位不变,其余位取反,如[-11]的反码:1111 0100
补码:
正数的补码就是其本身,即其原码,而负数则是在其反码的基础上,在最后一位加一,若是最后一位已经有1了,则将最后一位的1往前移一位
原码,反码,补码的运算意义:
将计算机内部的加减乘除运算都转换为加减运算,如把乘法变为加法,除法变为减法
位运算
左移 <<
把一个操作数转换为二进形式,然后把所有的数字向左移动对应的位数,高位移除(舍弃),低位的空位补0
如3<<2:
将数字3左移2位,
3转换为在计算机中二进制编码0000 0000 0000 0000 0000 0000 0000 0011
左移后:0000 0000 0000 0000 0000 0000 0000 1100
带符号右移 >>
按二进制形式把所有的数字向右移动对应的位数,低位移出,高位的空位补符号位,即正数补0,负数补1
不带符号右移 >>>
不用补符号位
左移和右移的数学意义:左移n为相当于原数乘以2的n次方,右移n位相当于除以2的n次方
按位与 &
如 8&2
首先将两个操作数都转换为二进制,分别将两个操作数的二进制的相同位比较,进行“与”运算,如果相同位为1,得到的对应位才为1,否则为0,所有为都比较后会得到一串二进制数,将其转换为十进制就得到最终结果
按位或 |
相同位进行或运算
位异或 ^
相同位的数相同,得到0,不同得到1
位非即反 ~
对一个操作数的二进制数进行取反
位运算的实际应用
判断奇偶
按位与,判断奇偶,a&1==0,则a为偶数,a&1==1,则a为奇数
取平均整数
// (x+y)/2可能产生溢出
int average(int x, int y) { //取x,y的整数平均数
return (x&y)+((x^y)>>1);
}
不用临时变量交换两个变量的值
x ^= y;
y ^= x;
x ^= y;
优化哈密尔顿最短回路的时间复杂度