一、原码、反码、补码
1 用二进制表示 00000001 |
int 为 4 个字节,32 位,1 位作为符号位,表示大小的有 31 位
为了方便运算,Java 整数二进制默认使用补码表示,正数和 0 的补码不变,负数的补码为反码加 1
0: 00000000000000000000000000000000 32个0 |
String s = Integer.toBinaryString(0x80000000); // 0x80000000: -2^31 |
- 1111 = 15 =
1*2^3 + 1*2^2 + 1*2^1 + 1*2^0
,0001 为 1,等于 2^0
二、移位运算符
<<
: 左移运算符
num << 1
,num 转换为二进制,长度固定,丢弃最左边指定位数,1 位,整体向左移动 1 位,后面补 0。
以 int 类型为例,4 个字节,32 位,表示 -2^31 ~ 2^31 - 1,10000000000000000000000000000000
~ 01111111111111111111111111111111
,最左位是符号位,当小于 2^31 - 1 时,最左边都是 0,所以 0 代表为正数,1 代表为负数。
当 num 为正数,且没有达到最大值时,即左边的 0 够多时,num << 1
相当于二进制每一位转十进制时在原来基础上再乘以 2,相当于 num 乘以 2。达到最大值后,正数可能变负数。
>>
: 右移运算符
num >> 1
,num 转换为二进制,丢弃最右边指定位数,1 位,整体向右移动 1 位,后面补符号位,如果 num 为正数,补 0,如果为负数,补 1。
当 num 为正数时,num >> 1
相当于 num 除以 2 取整(/)。
int 类型 4 字节,正数右移 31 位变为 0,右移 32 位相当于不移位,当大于 32 位时,先求余,再移位。long 类型 64 位取余。
>>>
: 无符号右移运算符
丢弃最右边指定位数,整体右移指定位,忽略符号位,后面空位都以 0 补齐。
因为左边没有符号,所以没有无符号左移。或者说,左移运算符就是无符号左移。
public static void main(String[] args) { |
733183670 << 1
,左移 1 位:
-733183670 >> 8
,右移 8 位:
-733183670 >>> 8
,无符号右移 8 位:
三、位运算符
- 先转换为二进制后再运算
&
按位与:1&1==1
/1&0==0
/0&0==0
,都为 1,则为 1,否则为 0|
按位或:1|1==1
/1|0==1
/0|0==0
,有一个为 1,则为 1,否则 为 0~
按位非:~1==0
/~0==1
, 单位为 bit,整数类型的话:~1==-2
–>~0b00000000000000000000000000000001==0b11111111111111111111111111111110
^
: 异或运算符1^1==0
/1^0==1
/0^0==0
,相同为 0,不同为 、1
四、逻辑运算符
&&
逻辑与:当左边表达式为 false 时,不再计算,直接为 false。规则跟&
一致||
逻辑或:当左边表达式为 true 时,不再计算,直接为 true。规则跟|
一致