java提供的位运算符有:
第一部分: &(位与),|(位或),^(位异或),~(位非)
第二部分: >>(右移),>>>(无符号右移),<<(左移)
其中除~为一元操作符,其他的都是二元操作符。
根据运算模式不同分为两部分
一.第一部分
&,|,^,~ 的运算规则
* &:有0则0
* |:有1则1
* ^:相同则0,不同则1
* ~:按位取反
案例:
class Demo1_Operator {
public static void main(String[] args) {
/*
* &,|,^,~ 的用法
* &:有0则0
* |:有1则1
* ^:相同则0,不同则1
* ~:按位取反
*/
System.out.println(6 & 3); //2
System.out.println(6 | 3); //7
System.out.println(6 ^ 3); //5
System.out.println(~6); //-7
}
}
110
& 011
-----------
010
b. 6 | 3 的二进制位运算过程:有1则1
110
| 011
-------------
111
c. 6 ^ 3 的二进制位运算过程:相同则0,不同则1
110
^ 011
-------------
101
d. 6 ^ 3 的二进制位运算过程:按位取反
00000000 00000000 00000000 00000110 //6的原码反码补码都是本身
11111111 11111111 11111111 11111001 // 对6取反得补码
- 00000000 00000000 00000000 00000001 //减1求反码
-----------------------------------------------------------
11111111 11111111 11111111 11111000 //反码,对反码进行除符号位以外其他位上按位取反。
10000000 00000000 00000000 00000111 //求得原码(-7)
位运算之面试题
核心要点:^的特点:一个数据对另一个数据位异或两次,该数本身不变。
题目:请自己实现两个整数变量的交换(不需要定义第三方变量)
案例:
class Demo2_Operator {
public static void main(String[] args) {
/*
* 位异或运算符的特点
* ^的特点:一个数据对另一个数据位异或两次,该数本身不变。
*/
int x = 10;
int y = 5;
//需要第三方变量
/*
int temp;
temp = x; //temp = 10
x = y; //x = 5
y = temp; //y = 10
*/
//不需要定义第三方变量,有弊端,有可能会超出int的取值范围
/*
x = x + y; //10 + 5 = 15
y = x - y; //15 - 5 = 10
x = x - y; //15 - 10 = 5
*/
//不需要第三方变量,通过^来做
x = x ^ y; // 10 ^ 5
y = x ^ y; // 10 ^ 5 ^ 5 y = 10
x = x ^ y; // 10 ^ 5 ^ 10 x = 5
System.out.println("x = " + x + ",y = " +
y);}
}
>>,>>>,<<的基本运算规则: a 位移运算符 b (a表示要进行位移的数,b表示位移的位数)
1. <<:左移 左边最高位丢弃,右边补齐0
2. >>:右移 最高位是0,左边补齐0;最高位是1,左边补齐1
3. >>>:无符号右移 无论最高位是0还是1,左边补齐0(正数适合,负数不适合,负数右移会变成正数)
4. 最有效率的算出2 * 8的结果
案例:
- class Demo3_Operator {
- public static void main(String[] args) {
- /*
- * <<:左移 左边最高位丢弃,右边补齐0
- * >>:右移 最高位是0,左边补齐0;最高为是1,左边补齐1
- * >>>:无符号右移 无论最高位是0还是1,左边补齐0
- * 最有效率的算出2 * 8的结果
- */
- //左移,向左移动几位就是乘以2的几次幂
- //System.out.println(12 << 1); //24
- //System.out.println(12 << 2); //48
- /*
- 00000000 00000000 00000000 00001100 12的补码
- (0)0000000 00000000 00000000 000011000 24的补码
- (00)000000 00000000 00000000 0000110000 48的补码
- */
- //System.out.println(-12 << 1); //-24
- //System.out.println(-12 << 2); //-48
- /*
- 10000000 00000000 00000000 00001100 -12的原码
- 11111111 11111111 11111111 11110011 -12的反码
- 11111111 11111111 11111111 11110100 -12的补码
- (1)11111111 11111111 11111111 11101000 -24的补码
- 11111111 11111111 11111111 11100111 -24的反码
- 10000000 00000000 00000000 00011000 -24的原码
- */
- //右移,向右移动几位就是除以2的几次幂
- //System.out.println(12 >> 1); //结果为 6
- //System.out.println(-12 >> 1); //结果为 -6
- /*
- 00000000 00000000 00000000 00001100 12的补码
- 00000000 00000000 00000000 00000110 6的补码
-
-
- 10000000 00000000 00000000 00001100 -12的原码
- 11111111 11111111 11111111 11110011 -12的反码
- 11111111 11111111 11111111 11110100 -12的补码
- 11111111 11111111 11111111 11111010(0) -6的补码
- 11111111 11111111 11111111 11111001 -6的反码
- 10000000 00000000 00000000 00000110 -6的原码
- */
-
- //System.out.println(12 >>> 1); //运算规则与>>一样 结果为6,在这里不做位运算详解了
- //System.out.println(-12 >>> 1); // 右移,最高位补0 结果2147483644
-
- /*
-
- 10000000 00000000 00000000 00001100 -12的原码
- 11111111 11111111 11111111 11110011 -12的反码
- 11111111 11111111 11111111 11110100 -12的补码
- 01111111 11111111 11111111 11111010(0) 2147483644的补码
- 01111111 11111111 11111111 11111010 2147483644的原码
- */
- //最有效率的算出2 * 8的结果 ,位运算的效率是比运算符的效率要高的.
- System.out.println(2 << 3);
-
- }
- }