位运算和View.MeasureSpec

前置技能

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。

注意

运算符的优先级

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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 14,259评论 0 38
  • 一、ECMAScript 一元运算符 一元运算符只有一个参数,即要操作的对象或值。它们是 ECMAScript 中...
    耦耦阅读 595评论 0 0
  • 高级运算符 文档地址 作为 基本运算符 的补充,Swift 提供了几个高级运算符执行对数传值进行更加复杂的操作。这...
    hrscy阅读 913评论 0 2
  • 案例代码下载 高级运算符 除了基本运算符中描述的运算符之外,Swift还提供了几个执行更复杂值操作的高级运算符。这...
    酒茶白开水阅读 947评论 0 0
  • 有没有一种强者的悲观主义?由于安康,由于漫溢的健康,由于生存的充裕而对生存中艰难、恐怖、险恶、成问题的东西有一种理...
    platonic_xxx阅读 270评论 0 0

友情链接更多精彩内容