一、原码、反码、补码 Java都是有符号数,二进制数的最高位是符号位,0表示正数,1表示负数。 【原码】是二进制数;【反码】是符号位不变,其它位取反;【补码】是反码+1,反码是补码-1。 正数三码合一,负数才分原码、反码和补码。 整数0的原码、反码和补码都是0。 计算机是以补码来运算的,我们看结果是看原码 。 正数 原码,反码,补码 2 原码 0000 0000 0000 0010 反码 0000 0000 0000 0010 补码 0000 0000 0000 0010 负数 原码,反码,补码 2 原码 0000 0000 0000 0010 反码 1111 1111 1111 1101 补码 1111 1111 1111 1110 二、位移:& | ~ ^ & 按位与,1 1得1,1 0得0,0 0得0(全真为真) | 按位或,1 1得1,1 0得1,0 0得0(全假为假) ~ 按位取反,0 得1,1 得0 ^ 按位异或,1 1得0,1 0得1,0 0得0 (相同为0,不同为1) 异或^ 的性质 1.a∧b,两个数相同等于0,两个数不同则等于1:0^N=N,N^N=0 2.a∧b∧c 异或可以随便交换位置。交换律、结合律:a^b=b^a,a^b^c=a^(b^c) 3.同一样的一批数进行异或,和谁先谁后无关,只要是同一批数进行异或结果是一样的。 练习
-3^3 = -2
-3 1000 0000 0000 0011 (原码)
1111 1111 1111 1100 (反码)
1111 1111 1111 1101 (补码)
3 0000 0000 0000 0011(补码)
得 1111 1111 1111 1110 (异或,补码)
1111 1111 1111 1101 (反码)
1000 0000 0000 0010 (原码)
结果是-2
2&3 = 2
2 0000 0000 0000 0010 (正数三码合一,补码)
3 0000 0000 0000 0011 (补码)
得 0000 0000 0000 0010
结果是2
13&7 = 5
13 0000 0000 0000 1101
7 0000 0000 0000 0111
得 0000 0000 0000 0101
2|3 = 3
2 0000 0000 0000 0010
3 0000 0000 0000 0011
得 0000 0000 0000 0011
结果是3
5|4 = 5
5 0000 0000 0000 0101
4 0000 0000 0000 0100
得 0000 0000 0000 0101
结果是5
~-5 = 4
-5 1000 0000 0000 0101 (补码)
1111 1111 1111 1010 (反码)
1111 1111 1111 1011 (补码)
~ 0000 0000 0000 0100 (取反)
得 0000 0000 0000 0100 (正数的补码等于原码)
结果是4
~2 = -3
2 0000 0000 0000 0010 (原码)
0000 0000 0000 0010 (补码)
~ 1111 1111 1111 1101 (取反,计算机是补码运算)
1111 1111 1111 1100 (补码-1,得反码)
1000 0000 0000 0011 (反码取反,得原码)
结果是-3
三、位移:<< >> >>> << 算术左移运算符,符号位不变,低位补0,num << 1,相当于num乘以2 >> 算术右移运算符,低位溢出,符号位不变,并用符号位补齐溢出高位,num >> 1,相当于num除以2 >>> 无符号右移,忽略符号位,低位溢出,高位补0
练习
1 >> 2 = 0;
1 << 2 = 4;
15 >> 2 = 3; //相当于 /2 /2
2 << 3 = 16; //相当于 *2 *2 *2