java 的原码、补码、反码小总结

先看一个代码吧:

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));
原文地址:https://www.cnblogs.com/zhuzi91/p/8818950.html