zoukankan      html  css  js  c++  java
  • 有趣的位运算-与或非

    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

  • 相关阅读:
    Log4J日志整合及配置详解
    SmartGit/Hg 4.0.1 发布
    Test Kitchen 0.7.0支持在OpenStack上对Opscode Chef进行集成测试
    RubyGNOME2 1.2.0 发布,支持 GTK+ 3
    PowerDNS Recursor 3.5 RC1 发布
    用于展现图表的50种JavaScript库
    Lambda表达式现状分析
    Node.js 0.8.18 / 0.9.7 发布
    CRUX 3.0 发布,轻量级 Linux 发行版
    Google 更新浏览器内的手写识别技术
  • 原文地址:https://www.cnblogs.com/ouym/p/8809063.html
Copyright © 2011-2022 走看看