反码,补码
将正数各个位取反,1变为0,0变为1所得二进制位反码,将反码+1所得到的二进制数为补码,补码为该正数在计算机中存储的负数形式,如,4在int类型占用4个字节32位,其原码,反码及补码如下
原码:00000000 00000000 00000000 00000100 反码: 11111111 11111111 11111111 11111011 补码: 11111111 11111111 11111111 11111100 (-4在计算机中的表示形式)
通过代码验证-4的二进制形式与上述补码一致
String binaryString = Integer.toBinaryString(-4);
System.out.println(binaryString);
无符号整数与有符号整数
无符号整数的所有位均表示数字,有符号整数的最高位表示符号,1表示负数,0表示正数。
对于byte,无符号时最小值为00000000=0,最大值为11111111=2^7+2^6+ ... 2^0=255,包含256个数字,有符号时,最小值为10000000=-2^7=-128,最大值为01111111=2^6+2^5+ ... 2^ 0=127
位运算
& 按位与,全为1时为1,否则为0
| 按位或,全为0时为0,否则为1
~ 按位非,0求非为1,1求非为0
^ 按位异或,相同为0,不同为1
示例(某些示例只显示的计算位,准确应该是32位,且以下示例也都可以通过java代码来验证结果是否正确)
1、& 按位与,全为1时为1,否则为0
3 & 5 = 0011 & 0101 = 0001 = 1 6 & 5 = 0110 & 0101 = 0100 = 4 7 & 5 = 0111 & 0101 = 0101 = 5
2、| 按位或,全为0时为0,否则为1
3 | 5 = 0011 | 0101 = 0111 = 7 6 | 5 = 0110 | 0101 = 0111 = 7 7 | 5 = 0111 | 0101 = 0111 = 7
3、~ 按位非,0求非为1,1求非为0
~ 2 = ~ 00000000 00000000 00000000 00000010 = 11111111 11111111 11111111 11111101
这是一个负数,不好直接计算,正数的负数形式是先反码然后+1得到反码即为该正数的负数形式,反过来,负数获取其对应正数,先-1,然后反码
~2-1 = 11111111 11111111 11111111 11111100
取反
00000000 00000000 00000000 00000011 = 3
所以~2 = -3
同理可得到~3=-4
4、^ 按位异或,相同为0,不同为1
2 ^ 3 = 0010 ^ 0011 = 0001 = 1 3 ^ 3 = 0011 ^ 0011 = 0000 = 0 4 ^ 7 = 0100 ^ 0111 = 0011 = 3
移位
1、左移,高位移除,低位补0
2 << 3 = 0010 << 3 = 0010 000 = 2^4=16
左移一位,相当于乘以2,左移n位,相当于乘以2的n次方
对于int类型,当移动超过了32为,相当于移动了movenNum%32位
对于long类型,若移动超过64位,相当于移动了moveNum%64位
byte和short类型,自动把这些类型扩大为int
2、右移,符号位不变,低位移除,高位补符号位
2 >> 2 = 0010 >>2 = 0000=0
右移一位,相当于除以2,左移n为,相当于除以2的n次方,但当移位之后的数值小于1时,实际移位得到的值为0,如上述2 >> 2,2 /2/2=0.5<1,最后结果为0
3、无符号右移,低位移除,高位补0
对于正数的无符号右移,与有符号右移得出的结果一样
System.out.println(8 >>> 2); // 2 System.out.println(8 >> 2); // 2
负数的无符号右移与有符号右移得出结果不同
/* * 1的原码,反码及补码如下 * 原码:00000000 00000000 00000000 00000001 * 反码:11111111 11111111 11111111 11111110 * 补码:11111111 11111111 11111111 11111111 (-1) * * 11111111 11111111 11111111 11111111 * 有符号右移两位,低位1去掉,高位补1,最后二进制码跟之前一样,结果还是-1 * 11111111 11111111 11111111 11111111 * 无符号右移2为得到00111111 11111111 11111111 11111111 * 该值通过2^29+2^28+ ... 2^0计算得出结果为1073741823 */ System.out.println(-1>>2); // -1 System.out.println(-1>>>2); // 1073741823
4、不存在无符号左移,因为左移时,低位补0,高位直接舍弃,不需要对符号位添加1或者0操作,在java代码中,如下写法会出现编译错误