前序
在看HashMap源码的时候,看到HashMap的hash函数里面有用到>>>的运算符,之前经常在除2操作用到>>运算符,但是还是第一次看到>>>,于是就来记录一下。
情景复现
hashMap的hash函数源码
因为里面主要是先获取key的hashCode,这是jvm生成的,所以我单独用1模拟hashCode
1 | System.out.println((h = 1) ^ (h >>> 16)); |
结果如下
1 | 情景复现: 1 |
步骤解析
这段代码主要由三段代码运算而成
- h直接赋值为1
- h>>>16位
- 步骤1与步骤2的异或运算
所以从结果推断出1>>>16结果为0
测试
1 | System.out.println("-12>>>2结果为:"+Integer.toBinaryString(-12>>>2)); |
1 | -12>>>2结果为:111111111111111111111111111101 |
分析
从结果可以看出,利用正数做操作时,>>与>>>结果没有变化,但是负数的操作时发生了变化,这个对比证明了>>>的操作与符号位有关。
- 正数操作
由于位运算时,利用Integer.toBinaryString方法输出不会输出前置0,所以可以推断两个运算符的操作都是右移n位补0
- 负数操作
由于负数存储的是它的补码,在进行>>运算的时候明显看到生成的二进制字符串补1,且长度比正数运算的时候要长,java在二进制中是不区分符号位的,所以最后的十进制表示的数会异常大。
总结
两个运算符,在进行正数移位的时候操作是一样的。但是在处理负数时,>>补1,是带符号操作的。而>>>补0,是无符号操作的。
本文首发于cartoon的博客
转载请注明出处:https://cartoonyu.github.io/cartoon-blog/post/java/无符号运算符与有符号运算符的区别/