前置技能
1. &
运算规则:两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为0。
private static final int MODE_SHIFT = 30;
private static final int MODE_MASK = 0x3 << MODE_SHIFT;
int mode = 1 << MODE_SHIFT;
System.out.println("mode: " + Integer.toBinaryString(mode));
System.out.println("MODE_MASK: " + Integer.toBinaryString(MODE_MASK));
System.out.println("mode & MODE_MASK: " + Integer.toBinaryString(mode & MODE_MASK));
结果:
mode和mode & MODE_MASK的结果应该是01000000000000000000000000000000,只是前面的0省略了
mode: 1000000000000000000000000000000
MODE_MASK: 11000000000000000000000000000000
mode & MODE_MASK: 1000000000000000000000000000000
2. ~
运算规则:如果位为0,结果是1,如果位为1,结果是0.
int size = 7;
System.out.println("size: " + Integer.toBinaryString(size));
System.out.println("MODE_MASK: " + Integer.toBinaryString(MODE_MASK));
System.out.println("~ MODE_MASK: " + Integer.toBinaryString(~ MODE_MASK));
System.out.println("size & ~ MODE_MASK: " + Integer.toBinaryString(size & ~ MODE_MASK));
结果:为了方便查看,已经在前面补0
size: 00000000000000000000000000000111
MODE_MASK: 11000000000000000000000000000000
~ MODE_MASK: 00111111111111111111111111111111
size & ~ MODE_MASK: 00000000000000000000000000000111
3. |
运算规则:两个数都转为二进制,然后从高位开始比较,两个数只要有一个为1则为1,否则就为0。
int size = 7;
int mode = 1 << MODE_SHIFT;
System.out.println("mode: " + Integer.toBinaryString(mode));
System.out.println("mode & MODE_MASK: " + Integer.toBinaryString(mode & MODE_MASK));
System.out.println("size: " + Integer.toBinaryString(size));
System.out.println("size & ~ MODE_MASK: " + Integer.toBinaryString(size & ~ MODE_MASK));
System.out.println("(mode & MODE_MASK) | (size & ~ MODE_MASK) : ");
System.out.println(" " + Integer.toBinaryString(((mode & MODE_MASK) | (size & ~ MODE_MASK))));
结果:为了方便查看,已经在前面补0
mode: 01000000000000000000000000000000
mode & MODE_MASK: 01000000000000000000000000000000
size: 00000000000000000000000000000111
size & ~ MODE_MASK: 00000000000000000000000000000111
(mode & MODE_MASK) | (size & ~ MODE_MASK) :
01000000000000000000000000000111
思考
- 为什么MeasureSpec.makeMeasureSpec不直接对size和mode进行或运算?
- 为什么MODE_SHIFT是30,能不能是31或者29?
个人见解
- 通过MODE_MASK和~MODE_MASK的与运算,截取数值,以保证数值的正确性
int size = Integer.MAX_VALUE;
int size_compute = size & ~ MODE_MASK;
System.out.println("size: " + size);
System.out.println("size: " + Integer.toBinaryString(size));
System.out.println("MODE_MASK: " + Integer.toBinaryString(MODE_MASK));
System.out.println("~ MODE_MASK: " + Integer.toBinaryString(~ MODE_MASK));
System.out.println("size & ~ MODE_MASK: " + Integer.toBinaryString(size_compute));
System.out.println("size_compute: " + size_compute);
int maxSize =( 1 << MODE_SHIFT) - 1;
System.out.println("maxSize: " + Integer.toBinaryString(maxSize));
System.out.println("maxSize: " + maxSize);
size: 2147483647
size: 01111111111111111111111111111111
MODE_MASK: 11000000000000000000000000000000
~ MODE_MASK: 00111111111111111111111111111111
size & ~ MODE_MASK: 00111111111111111111111111111111
size_compute: 1073741823
maxSize: 00111111111111111111111111111111
maxSize: 1073741823
引申:可不可以TextView.setWidth( Integer.MAX_VALUE )呢?
- 不能是31,因为int型只有32位,可以是29,但是size的最大值就变成了(1 << 29)-1。
注意
运算符的优先级
算术运算符优先级较高,关系和逻辑运算符优先级较低。多数运算符具有左结合性,单目运算符、三目运算符、赋值运算符具有右结合性。
网友评论