位运算(基本运算符)
记录一下位运算(&、|、^、~、>>、<<)
位运算概述
从现代计算机中所有的数据二进制的形式存储在设备中。即 0、1 两种状态。
计算机对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。
位运算符
符号 | 描述 | 运算规则 |
---|---|---|
`&` | 与 | 两个位都为1时,结果才为1 |
`|` | 或 | 两个位都为0时,结果才为0 |
`^` | 异或 | 两个位相同为0,相异为1 |
`~` | 取反 | 0变1,1变0 |
`<<` | 左移 | 各二进位全部左移若干位,高位丢弃,低位补0 |
`>>` | 右移 | 各二进位全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移) |
Mark一下
1.与运算符“&”
两个操作数中位都为1,结果才为1,否则结果为0
int a=129;
int b=128;
a 和b 与的结果是:128;
a的值是129,转换成二进制就是10000001.
b的值是128,转换成二进制就是10000000.
只有两个位都是1,结果才是1,结果就是10000000,即128.
2.或运算符“|”
两个位只要有一个为1,那么结果就是1,否则就为0
int a=129;
int b=128;
a 和b 或的结果是:129;
a 的值是129,转换成二进制就是10000001.
b 的值是128,转换成二进制就是10000000.
只有两个位有一个是1,结果才是1,结果就是10000001,即129.
3.非运算符“~”
如果位为0,结果是1,如果位为1,结果是0
int 2
非运算符~2=~原码0000 0000 0000 0010=补码1111 1111 1111 1101
//如果位为0,结果是1,如果位为1,结果是0
补码1111 1111 1111 1101转反码=1111 1111 1111 1100
//[-1] = [10000001]原 = [11111110]反 = [11111111]补
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1
则负数的反码转补码,符号位不变,最后一位减一
反码1111 1111 1111 1100转原码=1000 0000 0000 0011
结果为-3
4.异或运算符“^”
两个操作数的位中,相同则结果为0,不同则结果为1
int a=15;
int b=2;
a 与 b 异或的结果是:13
a 的值是15,转换成二进制为1111
b 的值是2,转换成二进制为0010
根据异或的运算规律,可以得出其结果为1101 即13
5.移位运算符
"<<" 左移运算符,将运算符左边的对象向左移动运算符右边指定的位数(在低位补0)
例:12 << 2
首先转化为二进制,12的二进制为0000 1100
将二进制数向左移两位,低位补0,得到0011 0000
最后将二进制数转化成十进制数,0011 0000转化为十进制为48
所以,12 << 2 = 48
例:-12 << 2
首先转化为二进制,-12的二进制为1111 0100
将二进制数向左移两位,低位补0,得到1101 0000
最后将二进制数转化成十进制数,1101 0000转化为十进制为-48
所以,-12 << 2 = -48
">>" "有符号"右移运算 符,将运算符左边的对象向右移动运算符右边指定的位数。使用符号扩展机制,也就是说,如果值为正,则在高位补0,如果值为负,则在高位补1.
例:20 >> 2
首先转化为二进制,20的二进制为0001 0100
将二进制数向右移两位,高位补符号位(0),得到0000 0101
最后将二进制数转化成十进制数,0000 0101转化为十进制为5
所以,20 >> 2 = 5
例:-20 >> 2
首先转化为二进制,20的二进制为1110 1100
将二进制数向右移两位,高位补符号位(1),得到1111 1011
最后将二进制数转化成十进制数,1111 1011转化为十进制为-5
所以,-20 >> 2 = -5
">>>" "无符号"右移运算 符,将运算符左边的对象向右移动运算符右边指定的位数。采用0扩展机制,也就是说,无论值的正负,都在高位补0.
例:15 >>> 2
首先转化为二进制,15的二进制为0000 1111
将二进制数向右移两位,高位补0,得到0000 0011
最后将二进制数转化成十进制数,0000 0011转化为十进制为3
所以,15 >>> 2 = 3
因为负数的符号位(最高位)为1,而无符号右移要在最高位补0,所以32位二进制要写全。带符号右移(>>),高位是补的符号位,前24位都是1。
(例子中的数比较小,8位足以表示;若是数字很大,要16位才能表示的话,那就是前16位都是1)
省略掉不影响计算;但这种情况比较特殊,补位和符号位不一样。
例:-15 >>> 2
首先转化为二进制,-15的二进制为1111 1111 1111 1111 1111 1111 1111 0001
将二进制数向右移两位,高位补0,得到0011 1111 1111 1111 1111 1111 1111 1100
最后将二进制数转化成十进制数,0011 1111 1111 1111 1111 1111 1111 1100转化为十进制为1073741820
所以,-15 >>> 2 = 1073741820
案例转载出处[点这里]