运算符
&:按位与。
|:按位或。
~:按位非。
^:按位异或。
<<:左位移运算符。
>>:右位移运算符。
<<<:无符号右移运算符。
位运算规则图示
操作 | 值1 | 值2 | 值3 | 值4 | 备注 |
---|---|---|---|---|---|
操作数1 | 0 | 0 | 1 | 1 | - |
操作数2 | 0 | 1 | 0 | 1 | - |
- | - | - | - | - | - |
与(&) | 0 | 0 | 0 | 1 | 对应位同为1取1,其他情况取0 |
或(|) | 0 | 1 | 1 | 1 | 对应位同为0时,结果为0,其余全为1. |
异或(^) | 0 | 1 | 1 | 0 | 相同取0,不同取1 |
非(~) | - | - | - | - | 非为取反 |
位运算示例代码
public static void main(String[] args) {
int a = 1255;
int b = 1205;
// 20 10100
printBinary(a);
// 26 11010
printBinary(b);
// a&b 10000 (同时为1则取1,其他情况取0)
xAnd(a, b);
xOr(a, b);
xNo(a);
xNo(b);
xEOr(a, b);
}
//字符截取
public static int binaryToDecimal(String s) {
int count = 0;
String str = "";
for (int i = 0; i < s.length(); i++) {
str = s.substring(s.length() - i - 1, s.length() - i);
if (Integer.valueOf(str) == 0) {
count += 0;
} else if (i == 0) {
count += 1;
} else {
count += add(i);
}
}
return count;
}
//v=v<<1 左移等
public static int add(int i) {
int v = 1;
for (int j = 0; j < i; j++) {
v <<= 1;
}
return v;
}
private static void xAnd(int a, int b) {
System.out.print(String.format("%s & %s = ", a, b));
printBinary(a & b);
}
private static void xOr(int a, int b) {
System.out.print(String.format("%s | %s = ", a, b));
printBinary(a | b);
}
private static void xNo(int value) {
System.out.print(String.format("%s: ~= ", value));
printBinary(~value);
}
private static void xEOr(int a, int b) {
System.out.print(String.format("%s ^ %s = ", a, b));
printBinary(a ^ b);
}
private static void printBinary(int value) {
String binaryString = Integer.toBinaryString(value);
print(binaryString);
println(String.format(" = %s", binaryToDecimal(binaryString)));
}
private static void println(Object value) {
System.out.println(value);
}
private static void print(Object value) {
System.out.print(value);
}
输出结果
10011100111 = 1255
10010110101 = 1205
1255 & 1205 = 10010100101 = 1189
1255 | 1205 = 10011110111 = 1271
1255: ~= 11111111111111111111101100011000 = -1256
1205: ~= 11111111111111111111101101001010 = -1206
1255 ^ 1205 = 1010010 = 82
位移运算
计算和存储使用二进制的补码。
正数的补码是本身。
负数的补码将除符号为所有位取反后+1
<< 左位移运算
: 符号位不变,低位补0。
1 << 1,转换为二进制即为
0000 0000 0000 0000 0000 0000 0000 0001 = 1
0000 0000 0000 0000 0000 0000 0000 0010 = 2
1 << 1 = 2
4 << 2 ,转换为二进制为
0000 0000 0000 0000 0000 0000 0000 0100 = 4
0000 0000 0000 0000 0000 0000 0001 0000 = 16
4 << 2 =16
6 << 5 ,转换为二进制为
0000 0000 0000 0000 0000 0000 0000 0110 = 6
0000 0000 0000 0000 0000 0000 1100 0000 = 192
6 << 5 = 192
>>右位移运算
:低位溢出,符号位不变,并用符号位补溢出的高位
20 >> 2,转换为二进制为
0000 0000 0000 0000 0000 0000 0001 0100 = 20
0000 0000 0000 0000 0000 0000 0000 0101 = 5
20 >> 2 = 5
9 >> 3 ,转换为二进制
0000 0000 0000 0000 0000 0000 0000 1001 = 9
0000 0000 0000 0000 0000 0000 0000 0001 = 1
9 >> 3 = 1
-9 >> 3,转换为二进制为
1111 1111 1111 1111 1111 1111 1111 0111 = -9
1111 1111 1111 1111 1111 1111 1111 1110
1111 1111 1111 1111 1111 1111 1111 0010 = -2
>>>无符号右移
:将最高位也当作数字,高位补0,做右位移运算
-9 >> 3,转换为二进制为
1111 1111 1111 1111 1111 1111 1111 0111 = -9
0001 1111 1111 1111 1111 1111 1111 1110 = 536870910
位移运算示例代码
public static void main(String[] args) {
leftMove(6, 5);
rightMove(-9, 3);
noCharRightMove(-9,3);
}
private static void leftMove(int value, int moveLength) {
printBinary(value << moveLength);
}
private static void rightMove(int value, int moveLength) {
printBinary(value >> moveLength);
}
private static void noCharRightMove(int value, int moveLength) {
printBinary(value >>> moveLength);
}