Java位操作指南

目录 [−]

  1. 原码,反码和补码
  2. 位操作符
  3. byte类型转int类型
  4. 参考

原码,反码和补码

这个是计算机的基础知识了。

+3的原码为00000011
-3的原码为10000011
第一位是符号位。

+3的反码为00000011
-3的反码为11111100
正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

+3的补码为00000011
-3的补码为11111101
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

使用补码可以将减法变为加法,而且0的问题也会解决。

Java中使用补码的格式保存byte,short,int,long类型的数据。 ( two's complement integer.)

位操作符

  • & 与。 按补码的每一位进行与操作。
  • | 或。 按补码的每一位进行与操作。
  • ^ 异或。 按补码的每一位进行与操作。
  • ~ 取反。 按补码的每一位进行与操作。
  • >> 带符号右移,高位补符号位。 正数右移一位相当于除以2。
  • >>> 无符号右移。高位补0。 正数右移一位相当于除以2。
  • << 左移,低位补0。 正数左移一位相当于乘以2。

除了~是一元操作符外其它都是二元操作符号。

byte类型转int类型

Java在将byte类型的数值转为int的过程中,会将符号位扩充, 10000000 -> 11111111111111111111111110000000。 这样数值会保持不变, 如下面的例子中字节类型的-128还是整型的-128。

1
2
3
4
5
6
7
byte b = -128;
int i1 = b & 0xff;
int i2 = b;
System.out.println(i1); //128
System.out.println(i2); //-128
System.out.println(Integer.toBinaryString(i1)); //10000000
System.out.println(Integer.toBinaryString(i2)); //11111111111111111111111110000000

但是, 如果byte是无符号的整数, 你就要考虑使用0xff进行与操作。这样得到的结果数值不变,避免Java自动进行符号位扩充。

0xff的补码为11111111, 意味着和它与操作将只保留后8位,并且结果总是非负数

参考

  1. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
  2. http://en.wikipedia.org/wiki/Bitwise_operation#Shifts_in_Java
  3. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op3.html