浅谈java中的移位运算符

这两天在学习hashmap源码,中间遇到很多位运算符,遂写下这篇文章来和大家一起交流。

在hashmap中的有这样一些代码:

    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4

    static final int tableSizeFor(int cap) {
        int n = cap - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

里面的就用到了 <<  和 >>> 两种位运算符,分别是左移运算符和无符号右移运算符。因为计算机是以0和1来处理数据的,所以在执行位运算符时先将数据转换为二进制然后再进行位运算。

1、左移运算符 <<  :(按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。)

举个例子,将7<<3,首先将数据转换为二进制数为:

 然后将高位三个数(左侧)移除,其余数字向左平移三位,最后低三位补0(右侧),得到数为:56

 

数学意义:在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。

注意:!!!当7<<29时,这是二进制数据为:

 此时,由于首位是1,也就是说数据变成了负数,这时我们就需要考虑变成负数的情况。

如果我们根据这个规则,将int类型数字左移32位,那这个数是不是就变成0了呢?当然不是,这时当位移超过类型最大位移数时,会对该数取余,即32%32=0,这就相当于该数没有位移,如果是36,就是36%32=4,这时就相当于左移4位。有兴趣的小伙伴可以用代码测试一下。

至于如何用二进制表示负数,这里简单说一下,就是该负数原码的补码,例如: -5

首先将5转换为二进制数:

 再得到-5的原码:(负数即为最高位(符号位)为1)

然后对其取反,获取其反码(符号位不变):即1变0,0变1

 最后获取到其补码(反码加一):如下为-5的二进制表示方法。

 注意:正数的反码与原码相同,正数的补码与原码相同!!!

扯远了扯远了,继续回到位运算符上来==、!

2、右移运算符 >>  :(按二进制形式把所有的数字向右移动对应位移位数,低位移出(舍弃),高位的空位补符号位,即正数补零,负数补1)

继续来举个例子:9>>2

先将9转为2进制数:

然后将低位2位数(右边)移除,其他数字向右平移两位,因为是正数,高位(左侧)补上两个0(负数则补上2个1),得到数位:2

数学意义:右移一位相当于除2,右移n位相当于除以2的n次方(取整)。

3、无符号右移  >>>  :按二进制形式把所有的数字向右移动对应位数,低位移出(舍弃),高位的空位均补零。这里与>>唯一有差别的地方就是无论数字正负,均在高位补0;

用-5作为例子:-5>>>3

无符号右移后:

此时负数变成了正数,这就是与>>位移的差别。

如果喜欢本文,请为我点赞,您的支持是我继续下去的动力,您也可以在评论区与我探讨或指正错误,最后别忘了关注一下我哦,谢谢。

你可能感兴趣的:(学习笔记,个人随笔)