美文网首页
位运算使用总结

位运算使用总结

作者: 裴庆圣 | 来源:发表于2019-07-19 18:15 被阅读0次

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

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

    从后往前二进制中每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进制数字了

    相关文章

      网友评论

          本文标题:位运算使用总结

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