要说位运算那么下面这些基础知识是一定要有的。
原码、反码、补码
原码
就是符号位加上这个数的绝对值的二进制表示
反码
正数即为原码
负数即符号位不变,其余位取反
补码
正数为原码
负数为其反码加1
基础运算
-
与 &
1001 0010 & 1001 1101 = 1001 0000
规则:同为1 则为1
-
或 |
1001 0010 | 1001 1101 = 1001 1111
规则:有一个或同为1 则为1
-
异或 ^
1001 0010 | 1001 1101 = 0000 1111
规则:相异则为1
-
左移 << 、右移>>、无符号右移>>>
int a = -2;//对应的二进制如下
1000 0000 0000 0010 >> 1 = 1000 0000 0000 0001 空位由0填充
1000 0000 0000 0010 << 1 = 1000 0000 0000 0100 空位由0填充
1000 0000 0000 0010 >>> 1 = 0100 0000 0000 0001 空位由0填充
可以看出左移和右移是不会影响符号位的,无符号右移会影响符号位,符号位会跟着移位
ColorInt
表示颜色有aRGB (透明度(默认为FF)、红、绿、蓝;每一个字段对应8个比特,即表示一个完整的颜色需要32位二进制 刚好就是一个int值)
@ColorInt
int color = 0x331122;
int alpha = color>>24 & 0xFF; //获取透明度 FF
int red = color>>16 & 0xFF; //获取红色 33
int green = color>>8 & 0xFF; //获取绿色 11
int blue = color & 0xFF; //获取蓝色 22
扩展
异或运算交换两数的值
有幸看到过这样的一段代码,不依靠第三个变量就交换两个变量的值。
int a = 10;
int b = 20;
a ^= b;
b ^= a;
a ^= b;
//这样操作完毕后,你会发现变量确实交换了值。
//但是这样会带来性能损失,速度比起使用临时变量会慢一些。
灵活使用与、或操作
在Android中经常有这样的应用
<TextView
...
android:gravity="center|top"/>
这里和前面提到的ColorInt类似,即这个gravity存储了多个状态。这些状态有一个特点:都是2的次幂。
举个栗子(这里略显啰嗦,起始都是上面讲过的):
状态‘center’ 对应一个数字2^3 = 8,在一个int的二进制中这样表示:0000 0000 0000 1000
状态‘top’ 对应一个数字2^2 = 4,在一个int的二进制中这样表示:0000 0000 0000 0100
将二者或运算得到:12 对应二进制 0000 0000 0000 1100
可以看到两个状态被放到了一起,且互不影响。接下来就通过与运算取出其中的状态
int center = 1<<3;//8
int top = 1<<2;//4
int gravity = center|top;
public boolean isCenter(){
return (gravity & center) == center;
}
public boolean isTop(){
return (gravity & top) == top;
}
发现错误的话,欢迎大家指出。