• 有趣的位运算-与或非


    1与运算(&)

    0 & a = 0
    
    1 & a = a

    a表示0或者1任意值。

    (1)与运算判断奇偶

    能被2整除的数是偶数(二进制的最后一位是0),结合与运算的性质不难得出:

    a & 1 = 0 偶数
    
    a & 1 =1 奇数

    (2)与运算+异或求平均值

    有int类型变量x、y,现需要求其平均值。

    首先要求x+y的和,再除以2,但是有可能x+y的结果会超过int的最大表示范围(这里强行加入位运算,x和y分别除2再相加也不会越界啦)

    (x&y)+((x^y)>>1)

    &运算:相当于十进制 相同位做加法的1/2

    0101 & 0011   结果:二进制0001             十进制 (2^0 +2^0)/2          这里的"^"代表次幂

    (3)HashMap源码中与运算的妙用

    对于任意给定的对象,只要它的 hashCode() 返回值相同,那么程序调用 hash(int h) 方法所计算得到的 hash 码值总是相同的。我们首先想到的就是把hash值对数组长度取模运算,这样一来,元素的分布相对来说是比较均匀的。但是,“模”运算的消耗还是比较大的,在HashMap中是这样做的:

    static int indexFor(int h, int length) {  
        return h & (length-1);  
    } 

    HashMap的底层数组的长度总是 2 的 n 次方,这是HashMap在速度上的优化。为什么呢?

    举个例子,若hashMap数组长度是15(1111),那么位置计算是h&(15-1),14(1110)的最后一位是0所以h的最后一位与操作永远是0,这样的后果是0001,0011,0101,1001,1011,1101这些尾数为1的空间永远不会放置数据,造成极大的空间浪费。

    而当底层数组的长度总是 2 的 n 次方时,h & (length-1)等价与h% (length-1),但是效率比前者要高很多。

    2或运算(|)

    0 | a = a
    
    1 | a = 1

    a表示0或者1任意值。

    |运算:相当于十进制 相同位做加法的1/2与不同位做加法求和

    0101 | 0011   结果:二进制0111             十进制 (2^0 +2^0)/2 +(2^2 +2^1)

    3非运算(~)

    ~运算规则是按位取反

    ~(0011)= 1100

  • 相关阅读:
    文件权限命令
    复制、移动文件及目录命令
    创建、删除文件及目录命令
    绝对路径和相对路径
    查找文件命令
    链接命令
    文本搜索命令
    编辑器 vim
    有参装饰器与迭代器
    闭包函数与装饰器
  • 原文地址:https://www.cnblogs.com/ouym/p/8809063.html
Copyright © 2020-2023  润新知