目录
逻辑右移:左边⽤ 0 填充,右边丢弃算术右移:左边⽤原该值的符号位填充,右边丢弃
规则:对两个数的对应⼆进制位进⾏与运算,只有对应的两个⼆进位都为 1 时,结果才为 1 。
规则:对两个数的对应⼆进制位进⾏或运算,对应的两个⼆进位只要有 1 ,或结果就为 1 。
规则:对两个数的对应⼆进制位进⾏异或运算,对应的两个⼆进位相同则为 0 ,相异则为 1 。
规则:对操作数的⼆进制位进⾏按位取反运算, 2 进制是 0 的变成 1 ,是 1 的变成 0
一、原码、反码、补码
其实说到 2 进制,在计算机内部,数值是以 2 进制的形式来进⾏表⽰和存储。后⾯要讲解的位运算的 操作符就是针对整数的⼆进制来进⾏运算的。所以下⾯讲解⼀下整数的 2 进制表⽰形式。
移位运算符:>>
位运算符 : & | ^
整数的 2 进制表⽰⽅法有三种,即原码、反码和补码;
整数分为有符号整数(signed)和⽆符号整数 (unsigned)。
有符号整数的原码、反码和补码的⼆进制表⽰中均由符号位和数值位两部分组成, 2 进制序列中,最⾼位的 1 位是被当做符号位,剩余的都是数值位,符号位都是⽤0 表⽰“正”,⽤1 表⽰“负”。
正整数的原、反、补码都相同。
负整数的三种表⽰⽅法各不相同,需要计算。
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码 +1 就得到补码。
由补码得到原码也是可以使⽤:取反, +1 的操作。
举例:
int a = -10;
原码:10000000 00000000 00000000 00001010
反码:11111111 11111111 11111111 11110101
补码:11111111 11111111 11111111 11110110
int a = 10;
原码:10000000 00000000 00000000 00001010
反码:10000000 00000000 00000000 00001010
补码:10000000 00000000 00000000 00001010
⽆符号整数的三种 2 进制表⽰相同,没有符号位,每⼀位都是数值位。
整数在内存中是以补码的形式存储的,整数在参与位运算的时候,也都是使⽤内存中的补码进⾏计算的,计算的产⽣的结果也是补码,需要转换成原码才是真实值。
二、位操作符
<< //左移操作符
>> //右移操作符
& //按位与操作符
| //按位或操作符
^ //按位异或操作符
~ //按位取反操作符
这些位运算的操作符,只适⽤于整数,不能应⽤于其他数据类型。
1、左移操作符是双⽬操作符
形式如下:
int num = 10;
num << i; //将num的⼆进制表⽰,左移i位
代码演示:
#include <iostream>
using namespace std;
int main()
{
int num = 10;
int n = num << 1;
cout << "n = " << n << endl;
cout << "num = " << num << endl;
return 0;
}
移位规则:左边抛弃、右边补 0
2、右移操作符是双⽬操作符
num >> i;//将num的⼆进制表⽰右移i位
#include <iostream>
using namespace std;
int main()
{
int num = -1;
int n = num >> 1;
cout << "n = " << n << endl;
cout << "num = " << num << endl;
return 0;
}
右移运算分两种:逻辑右移和算术右移,具体采⽤哪种右移⽅式取决于编译器,⼤部分的编译器采⽤的是算术右移。两种移位⽅式的规则如下:
逻辑右移:左边⽤ 0 填充,右边丢弃
算术右移:左边⽤原该值的符号位填充,右边丢弃
警告⚠⚠:对于移位运算符,不要移动负数位,这个是标准未定义的。
3、按位与操作符是双⽬操作符
a & b; //a和b按位与运算
规则:对两个数的对应⼆进制位进⾏与运算,只有对应的两个⼆进位都为 1 时,结果才为 1 。
#include <iostream>
using namespace std;
int main()
{
int a = -5;
int b = 7;
int c = a & b;
cout << c << endl;
return 0;
}
4、按位或操作符是双⽬操作符
a | b; //a和b按位或运算
规则:对两个数的对应⼆进制位进⾏或运算,对应的两个⼆进位只要有 1 ,或结果就为 1 。
#include <iostream>
using namespace std;
int main()
{
int a = -5;
int b = 7;
int c = a | b;
cout << c << endl;
return 0;
}
5、按位异或操作符是双⽬操作符
a ^ b; //a和b按位异或运算
规则:对两个数的对应⼆进制位进⾏异或运算,对应的两个⼆进位相同则为 0 ,相异则为 1 。
异或是满足交换律的。
#include <iostream>
using namespace std;
int main()
{
int a = -5;
int b = 7;
int c = a ^ b;
cout << c << endl;
return 0;
}
但是不建议使用异或操作符进行两个变量的交换,因为这样可读性差,并且效率低下,只能进行整数交换,应该使用temp这个临时变量进行两个变量的交换。
6、按位取反操作符是单⽬操作符
~a; //对a的⼆进制位按位取反
规则:对操作数的⼆进制位进⾏按位取反运算, 2 进制是 0 的变成 1 ,是 1 的变成 0
#include <iostream>
using namespace std;
int main()
{
int a = -5;
int b = ~a;
cout << b << endl;
return 0;
}