美文网首页
位运算和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

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