位运算符是以二进制为单位对操作数进行的操作和运算,位运算的操作数和结果都是整型变量。
运算符 | 运算 | 例子 | 解释 |
~ | 位反 | ~x | 将x按比特位取反 |
>> | 右移 | x>>a | X各比特位右移a位 |
<< | 左移 | X<<a | X各比特位左移a位 |
>>> | 不带符号的右移 | x>>>a | X各比特位右移a位,左边的空位填零 |
注:位运算符中,除~以外,其余均为二元运算符,操作数只能为整型和字符型数据。
补码
Java使用补码来表示二进制数,在补码表示中,最高位为符号位,正数的符号位为0,负数为1。补码的规定如下:
对正数来说,最高位为0,其余各位代表数值本身(以二进制表示),如:+42的补码为00101010。
对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。如:-42的补码为11010110(00101010按位取反再加1:11010101+1=11010110)。
在补码表示中,0的补码是唯一的,都为00000000(而在原码、反码表示中,+0和-0的表示是不相同的),而且,可以用11111111表示-1的补码(这也是补码与原码和反码的区别之一)。
按位取反运算符~
~是一元运算符,对数据的每个二进制位取反,即把1变为0,把0变为1.
例如:
0010101 = ~1101010
按位与运算符&
参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0。即:0&0=0,0&1=0,1&0=0,1&1=1。
例如:
00101010&00010111=00000010
与运算的作用如下:
1、按位与可以用来对某些特定的位清零,如对数11010110第2位和第5位清零,可让该数与11101101进行按位与运算:
11010110&11101101=11000100
2、按位与可以用来取某个数中某些指定的位,如要取数11010110的第2位和第5位,可让该数与00010010进行按位与运算:
11010110&00010010=00010010
按位或运算符|
参与运算的两个值,只要两个相应位中有一个为1,则该位的结果为1。即0|0=0,0|1=1,1|0=1,1|1=1。
例如:
00101010|00010111=00111111
按位或可以用来把某些特定的位置1,如对数11010110的第4位和第5位置为1,可以让该数与00011000进行按位或运算:
11010110|00011000=11011110
按位异或运算符^
参与运算的两个值,如果两个相应位相同,则结果为0,否则为1,即:0^0=0,0^1=1,1^0=1,1^1=0。
例如:
00101010^00010111=00111101
异或运算的作用如下:
1、 按位异或可以用来使某些特定的位翻转,如对数11010110的第4、5位翻转,可以将该数与00011000进行按位异或运算:
11010110^00011000=11001110
2、 通过按位异或运算,可以实现两个值的交换,而不使用临时变量,例如:交换两个整数a和b的值,可以通过下列语句实现:
a = 11010110,b = 01011001
a = a ^ b; //a=10001111
b = b ^ a; //b=11010110
a = a ^ b; //a=01011001
左移运算符<<
用来将一个数的各二进制位全部左移若干位,例如:a = a << 2,使a的各二进制位左移两位,右补0。若a = 00001111,则a<<2=00111100。高位左移后溢出,舍弃不起作用。在不产生溢出的情况下,左移一位相当于乘2,而且用左移来实现乘法比乘法运算速度要快。
右移运算符>>
用来将一个数的各二进制位全部右移若干位,例如:a = a>>2,使a的各二进制位右移两位,移到右端的低位被舍弃,最高位则移入原来高位的值。如a=00110111,则a>>2=00001101,b=11010011,则b>>2=11110100。
右移一位相当于除2取商,而且用右移实现除法比除法运算速度要快。
无符号右移运算符>>>
用来将一个数的各二进制位无符号右移若干位,与运算符>>相同,移出的低位被舍弃,但不同的是最高位补0。如a=00110111,则a>>>2=00001101,b=11010011,则b>>>2=00110100。
不同长度的数据进行位运算
如果两个数据长度不同(如byte型和int型),对它们进行位运算时,如a&b,a为byte型,b为int型,则系统首先会将a的左侧24位填满,若a为正,则填满0;若a为负,则左侧填满1.