美文网首页
位运算和View.MeasureSpec

位运算和View.MeasureSpec

作者: 群_b100 | 来源:发表于2019-10-20 10:27 被阅读0次

前置技能

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

思考

  1. 为什么MeasureSpec.makeMeasureSpec不直接对size和mode进行或运算?
  2. 为什么MODE_SHIFT是30,能不能是31或者29?

个人见解

  1. 通过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 )呢?

  1. 不能是31,因为int型只有32位,可以是29,但是size的最大值就变成了(1 << 29)-1。

注意

运算符的优先级

算术运算符优先级较高,关系和逻辑运算符优先级较低。多数运算符具有左结合性,单目运算符、三目运算符、赋值运算符具有右结合性。

相关文章

  • 位运算和View.MeasureSpec

    前置技能 1. & 运算规则:两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为0。 结果: ...

  • 位运算

    位运算包括逻辑运算和移位运算,相应地,位运算符包括逻辑运算符(包括~、&、|和^)和移位运算符(包括>>、<<和>...

  • 位运算和枚举

    我看iOS本身定义的枚举里面经常会使用左移(<<)来定义枚举的值,一开始我还不懂为啥要这么定义。这么处理的逻辑跟i...

  • Swift - 高级运算符介绍

    除了基本运算符之外,Swift还支持位运算和位移运算,包括:1、按位取反运算:操作符是 ~2、按位与运算:操作符是...

  • 001:位运算

    位运算符:3个位运算符 >>、<< 和 >>> 运算规则: 1、算数右移>>:低位溢出,符号位不变,并用符号位补溢...

  • 16_位运算符分析

    关键词: C语言中的位运算符、 左移和右移注意点、位运算防错准则、 位运算符和逻辑运算符的区别 1. C语言中的位...

  • 3、小众运算符の大课堂(一)

    较为简单の位运算符: & 位与运算| 位或运算^ 位异或运算~ 位取反运算 举例: 要做位运算,首先要把数据转...

  • 编程语⾔⾯试题之新版javase基础语法篇之运算符

    简介:⾯试中 短路运算符 和 位运算考点:计算机基础运算知识 难度【** *】 你知道 运算符 &和&&、|和||...

  • 17.位运算基础及实战要点

    17.位运算基础及实战要点 位运算符 算数移位与逻辑移位 位运算的应用 为什么需要位运算 机器里的数字表示方式和存...

  • 位运算与模运算的速度比较

    声明:不严谨之处还请指出 测试模运算的代码 测试位运算的代码 结论 同样效果下,位运算和模运算的差距,就不用我多说...

网友评论

      本文标题:位运算和View.MeasureSpec

      本文链接:https://www.haomeiwen.com/subject/shvomctx.html