zoukankan      html  css  js  c++  java
  • [JAVA]移位运算(左移<<,右移>>和无符号右移>>>)

    一、背景知识  

      整数在内存中是以二进制的形式存在的,而且存的是该整数的补码。最高位代表符号位,正数为0,负数为1

      正数的补码是其二进制本身,负数的补码则是 符号位保持1不变,其他位按位取反再加1,+0和-0的补码相同,都是0。

      负数在进行按位与运算时是以补码形式参与运算。(这个很好理解,因为负数在内存中本身就是以补码存储的)

    二、移位运算

      下面介绍三种移位运算,

      首先我们对5作运算。

      5在内存中的存储形式为:0000 0000 0000 0000 0000 0000 0000 0101

      1、左移<<

       符号位会被保留,数值位左移一位,低位补0,变为:

       0000 0000 0000 0000 0000 0000 0000 1010

       得到值为10

      2、右移>>

       符号位会被保留,数值位左移一位,数值位高位补0,变为:

       0000 0000 0000 0000 0000 0000 0000 0010

       得到值为2

      可以看到,左移相当于乘以2,右移相当于除以2,JDK中很多源码都采用了这种写法,效率高而且优雅

      3、无符号右移>>>

       >>>在右移时会将符号位当做数值位处理,一起右移,高位补0

       为了清楚地演示出符号位的变化,以-5为例:

       -5在内存中的存储形式为:1111 1111 1111 1111 1111 1111 1111 1011

       >>>1      后得到:   0111 1111 1111 1111 1111 1111 1111 1101

       值为2147483645,很明显,无论从10进制数值,还是从内存中的存储,都能看出,该值比Integer的最大值小2

       代码如下:

    /**
     * @Description:
     * @projectName:JavaTest
     * @see:PACKAGE_NAME
     * @author:郑晓龙
     * @createTime:2019/5/15 23:30
     * @version:1.0
     */
    public class ShiftOperationTest {
        public static void main(String[] args) {
            System.out.println(5<<1);
            System.out.println(5>>1);
            System.out.println(-5>>>1);
            System.out.println(Integer.MAX_VALUE);
        }
    }

      运行结果:

    10
    2
    2147483645
    2147483647

    最后,强迫症来了,为什么没有<<<    

    我认为是这样的:内存中是将整数以二进制的补码形式存放,最高位是符号位,左移时最高位有可能是1或0,符号位不能确定,也就无法满足无符号左移的定义,而右移可以规定高位补0,即可以确保符号位为0。

  • 相关阅读:
    影院售票系统
    返璞归真
    【C++】【STL】【map】基础知识干货
    书签-技术类
    正则表达式-正则表达式校验金额最多保留两位小数
    winCommand-cmd杀死进程
    idea快捷键-总结
    接口封装-泛型方法、泛型接口、lambda表达式【类似ios传递block】
    treeMap-get返回null,因为比较器出问题
    git-linux一个月更新80万行代码,如何保证项目稳健?
  • 原文地址:https://www.cnblogs.com/zhengxl5566/p/10873052.html
Copyright © 2011-2022 走看看