Java中的按位操作符

最近看 JDK 的源码, 看到一些 按位运算(Bitwise Operators), 这里做个总结.

1 按位运算符汇总

OperatorDescription
&Bitwise AND(按位与)
|Bitwise OR(按位或)
^Bitwise XOR(eXclusive OR, 按位异或)
~Bitwise Complement(按位取反)
<<Left Shift(左移)
>>Signed Right Shift(有符号右移)
>>>Unsigned Right Shift(无符号右移)

备注:
有符号右移: 右移时不移的符号位.
无符号右移: 右移时移动符号位. (可以理解为 把符号位当做普通的二进制位)

对于正数来说, 有符号右移 和 无符号右移 没有区别, 因为在右移完事了, 左边都要用 0 补齐.

左移: 也会 把符号位当做普通的二进制位.

优先级:

运算符综合性
~从右向左
<< >> >>>从左向右
&从左向右
^从左向右
|从左向右
=(赋值运算符)从右向左

2 按位与 &

按位与, 两位都为1结果才为1(全1则1):

xyx&y
000
010
100
111

例如:
3 & 5 结果为 1.

(decimal)    (binary)
     3     =  011
     5     =  101
------------------ 按位与(&)
     1     =  001

3 按位或 |

按位或, 有1位为1结果就为1(有1则1):

xyx|y
000
011
101
111

例如:
3 | 5 结果为 7.

(decimal)    (binary)
     3     =  011
     5     =  101
------------------ 按位或(|)
     7     =  111

4 异或 ^

异或, 两位不同则为1(相异为1):

xyx^y
000
011
101
110

例如:
3 ^ 5 结果为 6.

(decimal)    (binary)
     3     =  011
     5     =  101
------------------ 异或(^)
     6     =  110

5 按位取反 ~

按位取反:

x~x
01
10

例如:
~3 结果为 -4.

(decimal)    (binary)
     3     =  011
------------------ 按位取反(~)
     -4    =  100

特别注意:
按位取反 ~ 会改变符号位.

备注:
Java 中, int 占 32位, 第 1 位是 符号位, 其余 31 位是数字的二进制值.
在计算机中整数用 补码 表示.

原码: 符号位 和 数字的二进制表示.
反码: 在 原码 的基础上, 符号位不变, 其余位取反.
补码: 正数的补码就是原码本身, 负数的补码是 反码加1.

(decimal)    (binary)
     3      =  00000000 00000000 00000000 00000011
 ~3(补码)    =  11111111 11111111 11111111 11111100
 ~3(原码)    =  10000000 00000000 00000000 00000100

10000000 00000000 00000000 00000100 这就是 -4 的原码.

6 左移 <<

左移 会 把符号位当做普通的二进制位.
在左移完事后符号位不变的情况下, x 左移 n 位 相当于 x * 2n.

例如:
3 << 2 结果为 12.

(decimal)    (binary)
     3     =  0011
------------------ 左移2位(<<), 相当于: 3*(2*2)
     12     =  1100

7 有符号右移 >>

有符号右移 不会 把符号位当做普通的二进制位.
对于正数, 有符号右移时, 高位(左边)补0;
对于负数, 有符号右移时, 高位(左边)补1;

例如:
-5 >> 2 结果为 -2.

(decimal)    (binary)
     -5     =  111111111 11111111 11111111 1111011
------------------ 有符号右移 2位(>>)
     -2     =  111111111 11111111 11111111 1111110

5 >> 2 结果为 1.

(decimal)    (binary)
     5     =  000000000 00000000 00000000 0000101
------------------ 有符号右移 2位(>>) 相当于: 5/(2*2)
     1     =  000000000 00000000 00000000 0000001

对于正数, x 有符号右移(>>) n 位 相当于 x / 2n.

8 无符号右移 >>>

无符号右移 会 把符号位当做普通的二进制位.
不论正数还是负数, 无符号右移 >>> 高位(左边) 都补0.

(decimal)    (binary)
     -5     =  111111111 11111111 11111111 1111011
------------------ 无符号右移 2位(>>>)
     结果    =  001111111 11111111 11111111 1111110

9 验证程序

public class TCheck {
    public static void main(String[] args) {
        int a = 0xf; // 15
        printBinaryBeauty(a);
        System.out.println("=====0====");
        printBinaryBeauty(1 << 2); // 00000000 00000000 00000000 00000100
        printBinaryBeauty(1 << 3); // 00000000 00000000 00000000 00001000
        System.out.println("=====1====");
        printBinaryBeauty(1 << 31);      // 10000000 00000000 00000000 00000000
        printBinaryBeauty(~(1 << 31));   // 01111111 11111111 11111111 11111111
        System.out.println("=====2====");
        printBinaryBeauty(-5);      // 11111111 11111111 11111111 11111011
        printBinaryBeauty(-5 >> 2); // 11111111 11111111 11111111 11111110
        printBinaryBeauty(-5 >>> 2);// 00111111 11111111 11111111 11111110
        System.out.println("=====3====");
        printBinaryBeauty(5);       // 00000000 00000000 00000000 00000101
        printBinaryBeauty(5 >> 2);  // 00000000 00000000 00000000 00000001
        printBinaryBeauty(5 >>> 2); // 00000000 00000000 00000000 00000001
    }

    public static void printBinaryBeauty(int num) {
        System.out.print(num + " 的二进制表示: ");
        for (int i = 0; i < 32; i++) {
            int bit = (num & (0x80000000 >>> i)) >>> (31 - i);
            System.out.print(bit);
            if ((i+1) % 8 == 0) {
                System.out.print(" ");
            }
        }
        System.out.println();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值