zoukankan      html  css  js  c++  java
  • java 位运算 之 左移和右移理解

    <<(左移),>>(右移)皆属于位运算符.其运算比乘除快,所以我们可以用其优化代码。

    <<左移
    规则则是带符号位移,高位移出,低位补0,移动位数超过该类型的最大位数,则进行取模,如对Integer型左移34位,实际上只移动了两位。左移一位相当于乘以2的一次方,左移n位相当于乘以2的n次方。

    Integer i = 7;
    message(Integer.toBinaryString(i));
    int moveNum = 3;
    message(i << moveNum);
    message(Integer.toBinaryString(i << moveNum));
    
    输出结果
    the value is :111
    the value is :56
    the value is :111000

    从上面代码可以看出确实能证明,左移n为,相当于乘以2的n次方。如何验证其带符号位位移呢?看下面的例子

    Integer i = 1;
    message(Integer.toBinaryString(i));
    int moveNum = 31;
    message(i << moveNum);
    message(Integer.toBinaryString(i << moveNum));
    
    输出结果
    the value is :1
    the value is :-2147483648
    the value is :10000000000000000000000000000000

    从上面的输出结果可以看出,左移确实是带着符号位移动,向左移动了31位,1就移动到了最前面,也就是符号位上,得到了一个特殊的值,也就是-0的补码,用来代表-2的3次方。如果这个不懂,可以去看下源码反码补码的博客.

    Integer i = -7;
    message(Integer.toBinaryString(i));
    int moveNum = 33;
    message(i << moveNum);
    message(Integer.toBinaryString(i << moveNum));
    
    输出结果
    the value is :11111111111111111111111111111001
    the value is :-14
    the value is :11111111111111111111111111110010

    由上面的代码可以看出,我们左移的位数是33位,实际上却只左移了1位,证实了上面所说的移动位数超过该类型的最大位数,则进行取模

    >>右移

    规则则是低位移出,高位补符号位,移动位数超过该类型的最大位数,则进行取模,如对Integer型左移34位,实际上只移动了两位。

    Integer i = -7;
    message(Integer.toBinaryString(i));
    int moveNum = 1;
    message(i >> moveNum);
    message(Integer.toBinaryString(i >> moveNum));
    
    输出结果
    the value is :11111111111111111111111111111001
    the value is :-4
    the value is :11111111111111111111111111111100

    上面的二进制都是补码的形式,不要疑惑这个。可以看出上面的二进制代码,向右移动一位,然后在其高位补符号位,正数补0,负数补1.

    Integer i = 7;
    message(Integer.toBinaryString(i));
    int moveNum = 34;
    message(i >> moveNum);
    message(Integer.toBinaryString(i >> moveNum));
    
    输出结果
    the value is :111
    the value is :1
    the value is :1

    上面的代码,左移34位,实际上却只左移了两位,已经做过取模了。由于是正数,高位补0。

    >>> 无符号右移
    无符号位移是什么意思呢,就是右移的时候,无论正负数,高位始终补0。当然,它也仅仅针对负数计算有意义。

    Integer i = -7;
    message(Integer.toBinaryString(i));
    int moveNum = 1;
    message(i >>> moveNum);
    message(Integer.toBinaryString(i >>> moveNum));
    
    输出结果
    the value is :11111111111111111111111111111001
    the value is :2147483644
    the value is :1111111111111111111111111111100

    上面代码中,右移一位后的值,其高位省略了一位0,我们来计算其值。
    就是2的31次方 - 1 - 2º-2¹,其结果为2147483644

    <<< 无符号左移
    为什么没有这个呢?大家可以想一下。


    ————————————————
    原文:https://blog.csdn.net/koreyoshi326/java/article/details/85008708

  • 相关阅读:
    jdk环境变量配置(默认安装在c盘下)
    Less使用笔记
    Bootstrap4元素显示和隐藏
    npm常见命令及参数用法
    详解:cssrem插件 -- VS Code px转rem神器
    关于position:fixed的注意点
    解决:无法push到远程仓储
    解决:'git' 不是内部或外部命令,也不是可运行的程序
    小程序3-地图定位2
    转-前端开发流程
  • 原文地址:https://www.cnblogs.com/fightingtong/p/13230266.html
Copyright © 2011-2022 走看看