Android源码中常见的一些flag的运算理解与位移

ApplicationInfo是android.content.pm包下的一个实体类,用于封装应用的信息,flags是其中的一个成员变量public int flags = 0; 用于保存应用的标志信息。

用法:以系统的ApplicationInfo为例
  判断是否系统应用 :

  if((flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM ) 

       解读:ApplicationInfo.FLAG_SYSTEM 是二进制1左移0位,还是1,flags & 1 若等于1的话,则flags的二进制末位必须是1,
       因此只有flags是奇数,对应的应用才会是系统应用。其他的属性用法类似。

看看1|2|4|8分别对应的二进制数:
1 : 0001
2 : 0010
4 : 0100
8 : 1000
 
注意:它们通过“或运算”可以组成1~15的数,并且不会出现两种或两种以上的相同情况。
 

Android源码中,包括一些比较规范的源码中,通常会出现flag(我理解我标志位)。

可以这么认为:

    a&~b:  清除标志位b;
    a|b:     添加标志位b;
    a&b:    取出标志位b;    eg:取后三位  a&7
    a^b:    取出a与b的不同部分;
 
 参与运算的数以补码方式出现,因上述都是正整数,故源码等于补码。
 
移位运算 
 
(1)" < <" 左移:右边空出的位上补0,左边的位将从字头挤掉。在数字没有溢出的前提下,对于正数和负数,其值相当于乘2。 

左移里一个比较特殊的情况是当左移的位数(>>32)超过该数值类型的最大位数时,编译器会用左移的位数去模类型的最大位数,然后按余数进行移位,

int类型数值实际移位的次数是和32的余数,移位33次和移位1次得到的结果相同;long类型数值实际移位的次数是和64的余数,移位66次和2次得到的结构相同。如:

int i = 1, j = 0x80000000; //设int为32位
i = i << 33; // 33 % 32 = 1 左移1位,i变成2
j = j << 33; // 33 % 32 = 1 左移1位,j变成0,最高位被丢弃

再如:

int i = 0x40000000; //二进制的01000000…0000
i = i << 1;
那么,i在左移1位之后就会变成0x80000000,也就是2进制的100000…0000,符号位被置1,其他位全是0,变成了int类型所能表示的最小值,32位的int这个值是-2147483648,溢出.
如果再接着把i左移1位会出现什么情况呢? 在C语言中采用了丢弃最高位的处理方法,丢弃了1之后,i的值变成了0.


 (2)">>"右移:右边的位被挤掉。对于左边移出的空位,如果是正数则空位补0,若为负数补1。
 (3)">>>"运算符(无符号右移),右边的位被挤掉,对于左边移出的空位一概补上0。 
 
 
posted @ 2019-10-11 20:27  YOUNG++  阅读(717)  评论(0编辑  收藏  举报