先看一个代码吧:
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
这个应该很熟悉吧,是 java 里 HashMap 的计算 hash 值的方法.这里有一个运算符 "^",他其实就是使用补码来运算的.好了,那么我们下面来说说这些吧:
>原码。
就是当前数字的二进制表现形式,如-1的原码是1000 0001。 >反码
正数的反码就是本身。负数的反码是二进制保留符号位。剩余位取反,比如-1的反码是1111 1110; >补码
正数的反码、补码、原码都是一样的,负数的补码是在其反码的基础上+1,比如-1的补码是1111 1111。 正数的原码、反码、补码都相同。 负数的反码是除符合位为1外,其他位全取反,简单地说,负数求补码,“反码加1“。
这句话是不负责任的,因为原码、反码和补码概念中,存在符号位,总结一下,”取反加1“时符号位怎么办:
1)取反时,符号位不参与取反。
2)加1时,符号位参与加1。
3)特殊补码,即首位为1,其它位全是0。对于这种形式的补码,不要去求它的原码了,求出来也不对,它就表示该类型中的最小负数,比如10000000表示byte类型中的最小负数-128。 已知一个数的补码,求原码的操作分两种情况:
1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码.
2)如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取 反,然后再整个数加1.
例如,已知一个补码为11111001,则原码是10000111(-7):因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”;其余7位1111001取反后为0000110;再加1,所以是10000111. java有7种位运算符:与(&),或(|),异或(^),取反(~),左移(<<),有符号右移(>>),无符号右移(>>>)。
这7种位运算符,运算时,符号位都要参与运算。 具体的规则如下:
& 如果相对应位都是1,则结果为1,否则为0 (A&B),得到12,即0000 1100
| 如果相对应位都是0,则结果为0,否则为1 (A | B)得到61,即 0011 1101
^ 如果相对应位值相同,则结果为0,否则为1 (A ^ B)得到49,即 0011 0001
〜 按位补运算符翻转操作数的每一位,即0变成1,1变成0。 (〜A)得到-61,即1100 0011
<< 按位左移运算符。左操作数按位左移右操作数指定的位数。 A << 2得到240,即 1111 0000
>> 按位右移运算符。左操作数按位右移右操作数指定的位数。 A >> 2得到15即 1111
>>>按位右移补零操作符。左操作数的值按右操作数指定的位数右移,移动得到的空位以零填充。 A>>>2得到15即0000 1111 //1.&
int a = 10,b = 6;
/**
* a = 10 > 00000000 00000000 00000000 00001010
* b = 6 > 00000000 00000000 00000000 00000110
* &
* 2 > 00000000 00000000 00000000 00000010
*/
System.out.println(Integer.toBinaryString(a));
System.out.println(Integer.toBinaryString(b));
System.out.println(a & b); a = -10;
b = -6; /**
* a = -10 > 11111111 11111111 11111111 11110110
* b = -6 > 11111111 11111111 11111111 11111010
* &
* r = -14 > 11111111 11111111 11111111 11110010
*/ //-10
// 原码 10000000 00000000 00000000 00001010
// 反码 11111111 11111111 11111111 11110101
// 补码 11111111 11111111 11111111 11110110 //-6
// 原码 10000000 00000000 00000000 00000110
// 反码 11111111 11111111 11111111 11111001
// 补码 11111111 11111111 11111111 11111010 // -14
// 原码 10000000 0000000 00000000 00001110
// 反码 11111111 1111111 11111111 11110001
// 补码 11111111 1111111 11111111 11110010 System.out.println("a = " + a + ",补码是:" + Integer.toBinaryString(a));
System.out.println("b = " + b + " ,补码是:" + Integer.toBinaryString(b));
System.out.println("a ^ b is:" + (a & b));
System.out.println("结果的补码是:" + Integer.toBinaryString(-14));