重温那些不常用的运算符

1.非运算符 ( ~ )

int a=2;  
System.out.println("a 非的结果是:"+(~a));  

位运算都是补码运算的,2的二进制码应写8位的:00000010 按位取反为111111101,此时仍为补码,而补码转源码需要先-1,符号位不变再取反。换算为原码为:10000011 即-3。有个规律,取反都是原数+1再转为负数,如~19为-20

原码和补码转换关系

分两种情况,以八位原码转换补码为例:
正数(符号位为0的数)补码与原码相同.
负数(符号位为1的数)变为补码时符号位不变,其余各项取反,最后在末尾+1
例如:原码01100110,补码为:01100110
原码11100110,先变反码:10011001,再加1变为补码:10011010
计算机中的符号数有三种表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”,而数值位,三种表示方法各不相同。 在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
特性
1、一个负整数(或原码)与其补数(或补码)相加,和为模。
2、对一个整数的补码再求补码,等于该整数自身。
3、补码的正零与负零表示方法相同。

2.移位运算符 ( << >> >>> )

<< : 左移运算符,num << 1,相当于num乘以2
>> : 右移运算符,num >> 1,相当于num除以2
>>> : 无符号右移,忽略符号位,空位都以0补齐

为什么 -1 & 0x7F == 127

# 明确一点,计算机都是通过补码运算的
-1 = 10000001(原) => 11111110(反) => 11111111(补)
0x7F = 01111111(原) => 01111111(反) => 01111111(补)  
# 补码&运算后=01111111, 依然是补码,正数的补码等于原码,所以原码也是01111111, 也就是127

参考链接