如果对二进制码的转换不是很熟悉,建议先看原码 反码 补码 移码。
位运算是一种直接操作二进制位实现计算的方式,效率较高,在算法上会采用位运算。
JAVA支持的位运算符有:
位运算符描述运算规则
右移将操作符左边的操作数的二进制位全部右移操作符右边数值的位,正数高位补0,负数高位补1,低位丢弃。>>>
无符号右移将操作符左边的操作数的二进制位全部右移操作符右边数值的位,高位补0,低位丢弃。&
位与当运算符两边操作数二进制形式相同位置的值,逢0得0,其他得1。|
位或当运算符两边操作数二进制形式相同位置的值,逢1得1,其他得0。^
位异或当运算符两边操作数二进制形式相同位置的值,相同得0,不同得1。~
位非这个操作比较特别,它只需要一个操作数,将运算符后的二进制数反转,0变1,1变0 。
不存在 2 = -3,代表将12的二进制表示,右移2位,int型占4个字节,也就是占32位 由右向左
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 | -13的二进制 原码
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 | -13的二进制 反码
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 | -13的二进制 补码
|
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 | -13 >> 2 补码
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 | -13 >> 2 反码
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 | -13 >> 2 = -4 原码
如果是非负数和负数且是偶数的数进行右移n位,那么等于 ⌈ / ( 2 n ) ⌉ {\lceil / (2^n) \rceil} ⌈/(2n)⌉的运算
如果是负数且是基数的数进行右移n位,则等于 ⌊ / ( 2 n ) ⌋ \lfloor / (2^n) \rfloor ⌊/(2n)⌋的运算
向上取整:比自己大的最小整数;数学符号 ⌈ \lceil ⌈ ⌉ \rceil ⌉ 向下取整:比自己小的最大整数;数学符号 ⌊ \lfloor ⌊ ⌋ \rfloor ⌋
>>>
:无符号右移,运算符规则是:各二进制位全部右移若干位,高位补0,低位丢弃。
例如: 13 >>> 2
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 | 13的二进制
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 | 13 >> 2 = 3
例如: -13 >>> 2
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 | -13的二进制 原码
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 | -13的二进制 反码
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 | -13的二进制 补码
|
0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 | -13 >>> 2 = 1073741820 补码(原码) 最高位是0 为正数,补码即原码
&
:位与,运算规则是:当运算符两边相同位置的值,同为1时返回1,其他返回0。
例如: 13 & 2
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 | 13的二进制
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 | 2的二进制
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 | 13 & 2 = 0
例如: -13 & 2
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 | -13的二进制 补码
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 | 2的二进制
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 | -13 & 2 = 2
|
:位或,运算规则是:当运算符两边相同位置的值,同为0时返回0,其他返回1。
例如: 13 | 2
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 | 13的二进制
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 | 2的二进制
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 | 13 | 2 = 15
^
:位异或,运算规则是:当运算符两边相同位置的值,相同时返回0,不相同时返回1。
例如: 13 ^ 2
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 | 13的二进制
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 | 2的二进制
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 | 13 ^ 2 = 15
例如: 18 ^ 2
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 | 18的二进制
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 | 2的二进制
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 | 18 ^ 2 = 15
例如: -13 ^ 2
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 | -13的二进制 补码
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 | 2的二进制
|
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 | -13 ^ 2 补码
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 | -13 ^ 2 反码
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 | -13 ^ 2 = -15原码
~
:位非,这个操作比较特别,他只需要一个操作数,将运算符后二进制数反转,0变1,1变0 。
例如: ~13
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 | 13的二进制
|
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 | ~13的补码
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 | ~13的反码
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 | ~13=-14的原码
例如: ~-13
32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 | 位的序号
-------------------------------------------------------------------------------------- |
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 | -13的二进制 补码
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 | ~-13=12的补码
-
奇偶数
奇数的二进制的第一位(最低位)是1,那么通过 ( n & 1 ) = = 0 {(n \& 1)==0} (n&1)==0为true则为偶数
-
数的交换
交换A与B
a ^= b; b ^= a; a ^= b;
-
对 2 n 2^n 2n的数值进行取模计算
a % 2 n {a \% 2^n } a%2n 等价于 a & ( 2 n − 1 ) a\&(2^n-1) a&(2n−1)
-
生成第一个大于等于a的满足 2 n 2^n 2n的数
static final int MAXIMUM_CAPACITY = 1 > 1; n |= n >>> 2; n |= n >>> 4; n |= n >>> 8; n |= n >>> 16; return (n = MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; }
整体思想是通过移位和或运算,计算出cap二进制中比cap大且与2的n次方的二进制相差1的数。从出现1的最高位,往最低位方向,通过或运算进行位上的0变1的的方式进行计算,int型一共32位,1+2+4+8+16=31,这边一共移动了31位。而
cap - 1
是为了处理边界。当cap是8的时候,这个方法的应该返回8,但是如果不-1
,会返回16。 -
对 2 n 2^n 2n的数值进行乘法计算
a ∗ 2 n {a*2^n} a∗2n等价于 a < < n {a 31 == 0 ? a : ( ~ a + 1) a>>31==0?a:( a+1)