关于>>,<<,>>>运行符,你了解多少?

今晚在看hashmap源码,看到>>>,说实话,玩JAVA这么久,我还真没怎么关注过位运算符,虽然我一早就知道这个怎么用,但是三箭头的,我还真没留意过,其实这叫无符号右移位运算符。

static final int tableSizeFor(int cap) {
        int n = -1 >>> Integer.numberOfLeadingZeros(cap - 1);
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }

于是我测了一下,-1>>>1

System.out.println((-1 >>> 1));

2147483647

可能很多人不解,我验算了一下,确实如此,但这里得有一个补码的知识,我们的计算机并不是使用原码二进制,而是使用的补码的二进制,所以要知道为什么得出这个结果,得了解补码怎么来。我模拟了一下:

首先,-1的二进制表示是,一共32位,如下,思考:为什么32位,基础知识比较好的一下就反应过来,int类型就是32位的。再思考,为什么最高位是1?因为最高为1表示负数,0表示正数。

1. 以下是原码,但不是我们需要的。

10000000000000000000000000000001

2. 将原码取补码

1111 1111 1111 1111 1111 1111 1111 1111

3. 然后右移一位,这里要注意的就是 >>>是无符号右移,也就是说,右移后,最高位补0,即成了

0111 1111 1111 1111 1111 1111 1111 1111

4. 再次验算,将上面的转为原码(正数的补码与原码相同)

0111 1111 1111 1111 1111 1111 1111 1111

5. 这个二进制结果,转为10进制,就是2147483647。

 

说完了>>>,那就顺带说一下另外两个常用的

>>

即右移运算符,这个与正负数有关,正数右移,高位补0,负数右移,高位补1如:

System.out.println((-1 >> 1));
即:1111 1111 1111 1111 1111 1111 1111 1111右移一位,最高位补1,所以还是1111 1111 1111 1111 1111 1111 1111 1111,即还是-1,所以发现,-1右移多少位,结果都还是1.
  System.out.println((1 >> 1));
  即:00000000000000000000000000000001 右移一位,最高位补0,得到 00000000000000000000000000000000,即,得 0 ,所以发现,1右移多少位,结果都是0.

<<

即左移运行符,这个其实简单了,左移N位,低位补0即可,如:

System.out.println((-1 << 1));
即:1111 1111 1111 1111 1111 1111 1111 1111 左移1位,低位补0,得到 1111 1111 1111 1111 1111 1111 1111 1110,即 -2 ,记公式 ,-(2^n)即可,移几位,就是负2的几次方。
System.out.println((1 << 1));
即:00000000000000000000000000000001 左移一位,低位补0,得到00000000000000000000000000000010,即2,记公式 2^n即可,移几位,就是2的几次方。

 

最后,目前没用 <<< 这个运算符。

posted @   lythen  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示