Contents
  1. 1. 基本概念
  2. 2. 位运算符
    1. 2.1. 位与&
    2. 2.2. 位或|
    3. 2.3. 位非~
    4. 2.4. 位异或^
    5. 2.5. 有符号右移>>
    6. 2.6. 有符号左移<<
    7. 2.7. 无符号右移>>>
    8. 2.8. Note

基本概念

Java位运算是针对于整型数据类型的二进制进行的移位操作,我们首先需要弄明白两个问题,Java有哪些数据类型是整型数据类型和各数字进制之间转换问题。Java整型数据类型有:byte、char、short、int、long。1个字节占8位,即1byte=8bit。
常见数据类型及其所占位数如下:
位表格
Java中只有有符号整数,没有无符号整数(unsigned int),计算机在存储有符号整数时,是用该整数的补码进行存储的。只有有符号的整数才有原码,反码和补码(关于原码,反码,补码的详细介绍,参考这篇博文)。需要强调的一点是:由于计算机存储的是补码,正数的原,反,补码都一样,而负数则需要进行一定转换。以8位二进制数为例,00000001~01111111表示1~127,而负数若存储成原码形式,则10000001-11111111表示-1~-127,算上00000000=0一共127+127+1=255位,少了一位,所以要当成补码来计算,则10000001~11111111表示-127~-1,特别的10000000表示-128,所以8位二进制范围就是[-128,127],一共256位。因此计算机在进行位运算时,实际上都是补码的运算。

位运算符

以8bit为例,32bit同理

位与&

4&6
0000 0100
0000 0110
0000 0100
结果:4

位或|

-4|6
1111 1100
0000 0110
1111 1110(补码)
1000 0010(原码)
结果:-2

位非~

~4
0000 0100
1111 1011(补码)
1000 0101(原码)
结果:-5

位异或^

4^6
0000 0100
0000 0110
0000 0010
结果:2

有符号右移>>

正数,高位补0,负数,高位补1,实质等同于把这个数(十进制)除以2的n(位移位数)次幂
-4>>2
1111 1100
1111 1111
结果:-1

有符号左移<<

无论正数负数低位均补0,实质等同于把这个数(十进制)乘2的n(位移位数)次幂
-4<<2
1111 1100
1111 0000
结果:-16

无符号右移>>>

无论正数负数高位均补0,所以>>>结果一定是正数
-4>>>2
1111 1100
0011 1111
结果:2^6-1=63

Note

由于数据类型所占字节是有限的,而位移的大小却可以任意大小,所以可能存在位移后超过了该数据类型的表示范围,于是有了这样的规定:
如果为int数据类型,且位移位数大于32位,则首先把位移位数对32取模,不然位移超过总位数没意义的。所以4>>32与4>>0是等价的。
如果为long类型,且位移位数大于64位,则首先把位移位数对64取模,若没超过64位则不用对位数取模。
如果为byte、char、short,则会首先将他们扩充到32位,然后的规则就按照int类型来处理。

Contents
  1. 1. 基本概念
  2. 2. 位运算符
    1. 2.1. 位与&
    2. 2.2. 位或|
    3. 2.3. 位非~
    4. 2.4. 位异或^
    5. 2.5. 有符号右移>>
    6. 2.6. 有符号左移<<
    7. 2.7. 无符号右移>>>
    8. 2.8. Note