位运算使用总结

今天总结一下,二进制在开发过程中的使用

很多人都觉得 二进制和十进制转换是件麻烦的事,所以很少去用二进制,其实二进制和十进制的转换用的还是比较少,更多的是和十六进制进行转换,二进制和十六进制的转换就很简单方便了

从后往前二进制中每4位数字 代表十六进制中的1位数字

四进制是2位 ,八进制是3位 ,32进制是是5位 只要是2的n次方进制就代表二进制的n位
由于10不是2的整数次方,所以十进制的转换有点麻烦

1.如何来记这些转换数字呢

其实只要记2个公式就可以了 很简单,而且有关联的的两个公式
2的n-1次方 和 2的n次方-1

2^(n-1) 和 2^n -1
分别代表的是
1.只有第n位是1其他位置是0
2.第n位及后面都是1

这两个公式有什么用呢,后面在说

2. 补码怎么理解呢

说到底还是计算机不会算减法,只会算加法
如何把减法转成加法呢?
只要记住如何用二进制把相反的两个数加起来为0,举个例子

-15 + 15 = 0
? + 00000000000000000000000000001111 = 0
问号的部分很容易就想起来,先使32位全变成1,然后在+1就会超出长度,变成初始值0

3. 位运算

  • 位与 &

同为1才能取1 所以 只要记住

a & b = c 操作后 c的值肯定小于等于a或b

1.HashMap中取keyHashCode 就运用到了&操作这样使HashCode的下标不会大于2^n,这也就是为什么HashMap每次扩容都是x2

  1. 如果东、南、西、北 分别用 0、1、2、3表示,当前方向为d(d属于[0,1,2,3])每次都顺时针或逆时针旋转90度,多次旋转后如何获取当前的方向呢?(力扣1041. 困于环中的机器人)
    顺时针旋转90度就可以用 d = (d + 1) & 3
    逆时针旋转90度就可以用 d = (d - 1) & 3
    就可以不用if else来做>3<0的判断了
  • 位或 |

只要有1就取1 所以 只要记住

a | b = c 操作后 c的值肯定大于等于a或b

  • 位非 ~

0变1 1变0

前面3个组合使用

对于一个JavaBean,如果有多个boolean属性,如果使用多个字段来保存信息,当有多个对象时候,传输数据,储存数据都很大,这时,就可以用int mFlags 来管理这些属性

    private int mFlags;

    //mFlags是否true
    public boolean isFlags(int mFlags) {
        return (this.mFlags & mFlags) == mFlags;
    }

    //设置mFlags 为true
    public void addFlags(int mFlags) {
        this.mFlags |= mFlags;
    }

    //设置mFlags为false
    public void removeFlags(int mFlags) {
        this.mFlags &= ~mFlags;
    }

    //设置mFlags属性value
    public void setFlags(int mFlags, boolean value) {
        if (value) {
            addFlags(mFlags);
        } else {
            removeFlags(mFlags);
        }
    }

每个属性可以用0b1、0b10、0b100、0b100等,用每个位代表属性,1为true ,0为false,常用16进制表示flag,0x1、0x2、0x4、0x8、0x10
这样一个字段就可以表示多个属性了

  • 位异或 ^

不一样取1,一样取0 ( 不要这样记 )

a ^ b 把b上有1的位置对应a的位置数字取反
即 b=011010 就是把a的从右往左数第2、4、5位的数字取反

异或很神奇,a ^ b 指b上有1的位置对应a的位置数字取反
同理也指a上有1的位置对应b的位置数字取反
如果两次取反同一位置,就和原来的数字一样,即a ^ b ^ b = a (a ^ b ^ a = b),即两个相同的数字会被抵消
这样,来看看下面的操作作用是什么

 a = a ^ b;
 b = a ^ b;
 a = a ^ b;
  • 左移<<

位置往左移,右边补0

  • 右移 >>

位置往右移,左边补0(符号位不参与移动)

  • 无符号右移 >>>

位置往右移,左边补0

常用1个32位的int 来存储多个数值

  1. 比如ip地址 255.255.255.255 一个255可以用8位来存储,一个ip地址可以用32位的int型来存储
  2. 比如Android中的MeasureSpec 高2位用来记录mode 低30位来记录数值
  3. HashMapHashCode的前16位和后16混合
  4. Bitmap中的图片存储位置的颜色属性,我们都知道ARGB都是用255(11111111),255(11111111),255(11111111),255(11111111)来表示的,即A、R、G、B、分别占用8位,一个32位int型就可以记录颜色信息
    对应的属性是8888;还有565 ,4444,表示一个32位int型可以记录两个位置的颜色,就比8888少了一半的内存
    如何在1个32位Int型中取出对应的值,就用到了位移操作

现在知道 2^(n-1) 和 2^n -1是记忆进制转换的关键了吧
1.只有某位是1其他位为0 ~ 2.连续低位是1
就是我们常见的10进制数字了

你可能感兴趣的:(位运算使用总结)