与或非是啥?
常用的位运算符: “&” “|” “~”(与 或 非)。
1,“&”运算符的运算规则:两个运算位同时为1时结果为“1”,否则为“0”。
如:1&0=0; 1&1=1; 0&0=0; 0&1=0;
2,“|”运算符的运算规则:两个运算位只要有一个为“1”时结果为“1”,否则为“0”。
如:1|1=1; 1|0=1; 0|1=1; 0|0=0;
3,“~”运算符的运算规则:如果位为“0”,结果为“1”,如果位为“1”,结果为“0”
如:~0=1; ~1=0;
但是,在计算机中不是这样的,结果为:
System.out.println("~0="+~0); 结果为:-1
System.out.println("~1="+~1); 结果为:-2
解析:这并不是计算机出问题了,而是计算机内部编码的原因。
4,计算机内部编码:
对于整数,计算机内部最高位表示符号位: 0为正 1为负。
对于负数,为了方便计算,计算机用补码表示其值。(原码到补码的转换规则:除符号位外,原码各位取反,然后加1得到补码)。
解释为啥~0=-1:
0在计算机中的二进制形式: 0000 0000
0经过非运算(“~”)后: 1111 1111 (计算机中存的都是原码)
反码: 1000 0000
补码: 1000 0001 (即:-1)
在Android中的应用
1,场景一:或运算符的使用
android:layout_gravity="bottom | right" 在这里bottom和right在位上肯定是错开的,这样才能同时保存该控价“居右”和“底部”的属性。
//0x001=0000 0001
int right=0x001;
//0x002=0000 0010
int bottom=0x002;
//那么 right|bottom= 0000 0011
上面的位错开是为了或运算时,进行值的保留。这样两个状态就能够保存在一个属性里面啦。
(暂时可以理解为将两个状态放在一个集合里)
2,场景二:与运算的使用
上面介绍了如何组装一个值。安卓源码中怎样知道我们设置了right这个居右的状态呢?这就需要“与”运算来取值。
int right=0x001;
int bottom=0x002;
int top=0x008;
int state=right | bottom;
system.out.println("是否存在right="+((state & right)==right));
system.out.println("是否存在top="+((state & top)==top));
//打印结果: 是否存在right=true; 是否存在top=false;
从上面代码可以清晰的看出,用“与”运算符可以取值 、判断是否存在这个状态。
(暂时可以理解成判断某个状态是不是在集合里)、
3,场景三:非运算的使用
当我们想剔除集合中的一个状态的时候要怎么做呢? 用 “非”和“与”运算符联合使用,如下代码。
int right=0x001; //1
int bottom=0x002; //2
int top=0x008; //8
int state=right | bottom; //3
System.out.println("剔除rightz状态前"+state); //剔除rightz状态前 3
state&=~right;
System.out.println("剔除rightz状态后"+state); //剔除rightz状态后 2
state&=~top;
System.out.println("剔除不存在的状态top后"+state); //剔除不存在的状态top后 2
如上就可以通过 “与” “非”的联合运算实现剔除集合中状态的功能。
总结:
或运算符整合值(组成状态集合)
与运算符取值(集合中取出状态)
与非剔除值(集合中移除状态)