位运算与移位运算
2020-09-21 本文已影响0人
泡泡茶壶大人
原码、反码、补码
对于有符号的数来说:
- 二进制的最高位是符号位:
0
表示正数,1
表示负数;
示例:
1
和-1
的byte
(8位) 类型再内存中分别表示为:
1 ==> [0000 0001]
-1 ==> [1000 0001]
- 正数的原码、反码、补码都一样;
- 负数的反码 =
原符号位不变,其他位取反 (0->1 1->0)
- 负数的补码 = 反码 + 1
- 0的原码、反码、补码都是0
- 在计算机运算时,都是以补码的方式运算的
示例:
10: 8位原码、反码、补码: 0000 1010 6: 8位原码、反码、补码:0000 0110 -6: 8位原码:1000 0110 反码:1111 1001 补码:1111 1010 -10: 8位原码:1000 1010 反码:1111 0101 补码:1111 0110
位运算符
按位与 (
&
): 两位全为1,结果为1,否则为0示例:
计算 10 & -6 10的补码:0000 1010 -6的补码:1111 1010 ---------------------- 结果补码: 0000 1010 ==> 正数,即为 10 计算 -10 & -6 -10的补码:1111 0110 -6的补码: 1111 1010 ---------------------- 结果补码: 1111 0010 ==> 反码:1111 0001 ==> 原码:1000 1110 即 -14
按位或 (
|
): 两位只要有一个为1,结果为1,均为不1,即为0示例:
计算 10 | 6 10的补码:0000 1010 6的补码: 0000 0110 ----------------------- 结果补码:0000 1110 ==> 正数,即为 14 计算 10 | -6 10的补码:0000 1010 -6的补码:1111 1010 ----------------------- 结果补码:1111 1010 ==> 反码:1111 1001 ==> 原码:1000 0110 即 -6
按位异或 (
^
): 只有当两位不相同时,结果为1,否则为0示例:
计算 10 ^ 6 10的补码:0000 1010 6的补码: 0000 0110 ----------------------- 结果补码:0000 1100 ==> 正数,即为 12 计算 10 ^ -6 10的补码:0000 1010 -6的补码:1111 1010 ----------------------- 结果补码:1111 0000 ==> 反码:1110 1111 ==> 原码:1001 0000 即 -16
任何数与0异或,结果都是其本身。
利用异或还可以实现两个数的交换:
int a = 10; int b = -6; a = a ^ b; //生成补码: 1111 0000 b = a ^ b; //生成补码: 0000 1010 ==> 10 a = a ^ b; //生成补码: 1111 1010 ==> 原: 1000 0110 即-6 //以上通过按位异或,实现a、b两个数的交换。
//交换方法二: (补充) a = a + b; b = a - b; a = a - b;
非(
~
): 按位取反,包括符号位计算 ~10 10的补码:0000 1010 ----------------------- 结果补码:1111 0101 ==> 反码:1111 0100 ==> 原码:1000 1011 即 -11 计算 ~-6 -6的补码:1111 1010 ----------------------- 结果补码:0000 0101 ==> 正数,即 5
移位运算符
右移:低位溢出,符号位不变,并用符号位补溢出的高位
符号:
>>
/* 位右移: * 右移一位,相当于原数值 / 2, * 右移两位,相当于原数值 / 4, * 右移n位,相当于原数值 / 2^n * 结果没有小数(向下取整) */ 计算 10 >> 1 10的补码:0000 1010 ----------------------- 结果补码:0000 0101 ==> 正数,即 5 计算 10 >> 2 10的补码:0000 1010 ----------------------- 结果补码:0000 0010 ==> 正数,即 2 计算 11 >> 1 11的补码:0000 1011 ----------------------- 结果补码:0000 0101 ==> 正数,即 5 计算 -11 >> 1 -11的补码:1111 0101 ----------------------- 结果补码: 1111 1010 ==> 反码:1111 1001 ==> 原码:1000 0110 即 -6
左移:符号位不变,低位补0
符号:
<<
/* 位左移: * 左移一位,相当于原数值 * 2, * 左移两位,相当于原数值 * 4, * 左移n位,相当于原数值 * 2^n */ 计算 10 << 1 10的补码:0000 1010 ----------------------- 结果补码:0001 0100 ==> 正数,即 20 计算 10 << 2 10的补码:0000 1010 ----------------------- 结果补码:0010 1000 ==> 正数,即 40 计算 11 << 1 10的补码:0000 1011 ----------------------- 结果补码:0001 0110 ==> 正数,即 22 计算 -11 << 1 -11的补码:1111 0101 ----------------------- 结果补码: 1110 1010 ==> 反码:1110 1001 ==> 原码:1001 0110 即-22
参考文章:
https://www.jianshu.com/p/c6362f67ef5b
https://www.jianshu.com/p/60952a44841f