位运算符以及其的用途
1. & --------按位与运算
"&"是双目运算符双目运算符就是有两个操作数
只有当二进制对应位上都是1的时候结果才为1。
a | b | a&b |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
用途:
-
限制数值在某个范围内
int number = 10; int res = 7 & number;
在这段代码中,
7 & number
是一个按位与运算。首先,将
7
和number
转换为二进制表示:7 : 0000 0111 number: 0000 1010
然后进行按位与运算:
0000 0111 (7) & 0000 1010 (number) ----------------------- 0000 0010 (2)
按位与运算的规则是,只有在相应的位上都是 1 时,结果才为 1;否则,结果为 0。因此,在这个例子中,只有第二位上的 1 对应的位置都是 1,其他位都为 0。所以,最终的结果
res
为 2。因此,
res
的结果为 2。 -
判断奇偶数
二进制中只有当最后一位二进制数为1的时候才表示奇数,而相反只有当最后一位二进制数为0的时候才表示偶数,所以利用“&”的特点,我们可以得到:
- 与奇数:7&1
7 : 0000 0111 & : 1 ----------------------- 0000 0001 (1)
- 与偶数:8&1
8 : 0000 1000 & : 1 ----------------------- 0000 0000 (0)
代码如下:
if((x&1) == 1) printf("x是奇数\n"); else if((x&1) == 0) printf("x是偶数\n");
2. ^ --------按位异或运算
“^”是双目运算符,对底层二进制串进行运算,比算术运算快得多,规则为:相同为0,不同为1。
a | b | a^b |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
性质:
假设num
为任意实数
-
0 ^ num= num
:0^77 : 0000 0111 ^ : 0000 0000 ----------------------- 0000 0111 (7)
即:0与任何数进行异或,结果都是任何数
-
num ^ num = 0
:7^77 : 0000 0111 ^ : 0000 0111 ----------------------- 0000 0000 (0)
即:任何数与自身进行异或,结果都是0
-
异或运算的交换律:a ^ b = b ^ a
a ^ b = b ^ a
重点:我们可以将异或运算理解为二进制的无进位相加!也就是说,当两个数异或的时候,如果某一位同为1,则该位为0并且不向前进位。
用途:
-
交换两个数字的值
public void swap(Integer a, Integer b) { a = a ^ b; b = a ^ b;//b=a ^ b ^ b 相等异或为0,0与任何数异或得任何数 即b=a a = a ^ b;//a=a ^ b ^ a 相等异或为0,0与任何数异或得任何数 即a=b }
注意:在于当交换的是同一个索引时,也就是i和j相等时,会导致结果不正确。交换后最终为0
代码如下:
public void swap(int[] arr,int i,int j) { //这里实参i,j是相同的下标 即arr[i]==arr[j] arr[i] = arr[i] ^ arr[j]; arr[j] = arr[i] ^ arr[j];//arr[j] =arr[i] ^ arr[j] ^ arr[j] 相等异或为0,0与任何数异或得任何数 即arr[j] =0 arr[i] = arr[i] ^ arr[j];//arr[i] =arr[i] ^ arr[j] ^ arr[i] 相等异或为0,0与任何数异或得任何数 即arr[i] =0 }
-
只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
public static int findOne(int[] arr){ //初始为0, int res=0; for (int i : arr) { res^=i; } return res; }
提示:所有重复出现的数据会被抵消为0,剩下的就是只出现一次的
3. | --------按位或运算
“|”是双目运算符,
只有当二进制对应位上有一个为1,结果为1
a | b | a或b |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
用途:
-
对一个数据的某些位 - 置 1
例:将 X=10100000 的低 4 位 置 1 ,用 X | 0000 1111 = 1010 1111 即可得到
X : 1010 0000 (160) | : 0000 1111 (15) ----------------------- 1010 1111 (175)
-
强行变成最接近的偶数 即:把二进制最末位变成 0
对这个数 or 1 之后会使最后以为保持不变(奇数),或者加1(偶数),目的就是将这个数变为奇数,之后之后再减一就可以了
7 : 0000 0111 ^ : 0000 0001 ----------------------- 0000 0111 (7)
4. ~ -------求反运算符
“~”为单目运算符(只有一个操作数),具有右结合性(从右向左执行计算),
a | ~a |
---|---|
0 | 1 |
1 | 0 |
5. << -----左移运算符
“<<”是双目运算符,将二进制位进行左移操作,
左移n位就是乘以2的n次方。
“<<”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。
6.>> --------右移运算符
“>>”是双目运算符,将二进制位进行右移操作,
右移n位就是除以2的n次方。
“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。同时注意,>>运算符是用符号位来填充高位的。