zoukankan      html  css  js  c++  java
  • Java 移位操作>>,<<,>>> 位逻辑运算符 &, |,~,^

    首先要明白一点,这里面所有的操作都是针对存储在计算机中中二进制的操作,那么就要知道,正数在计算机中是用二进制表示的,负数在计算机中使用补码表示的。

    左移位:<<,有符号的移位操作
    左移操作时将运算数的二进制码整体左移指定位数,左移之后的空位用0补充


    右移位:>>,有符号的移位操作
    右移操作是将运算数的二进制码整体右移指定位数,右移之后的空位用符号位补充,如果是正数用0补充,负数用1补充。

    例子:

    public static void main(String[] args)
    {
    System.out.println(3<<2);//3左移2位
    System.out.println(-3<<2);//-3左移2位
    System.out.println(6>>2);//6右移2位
    System.out.println(-6>>2);//-6右移2位
    }

    输出结果

    12
    -12
    1
    -2
    下面解释一下:

    ? ? ? 00000000 00000000 00000000 00000011 +3在计算机中表示
    00000000 00000000 00000000 0000001100 左移2位,补0,结果为12

    ----------------------------------------------------------------------------------------------

    ? ? ? 00000000 00000000 00000000 00000011 +3在计算机中表示
    11111111 11111111 11111111 11111100
    11111111 11111111 11111111 11111101 -3在计算机中表示
    11111111 11111111 11111111 1111110100 左移2位,补0,结果为负数,就是补码了,求原码
    10000000 00000000 00000000 00001011
    10000000 00000000 00000000 00001100 结果-12
    ----------------------------------------------------------------------------------------------

    这也说明了一个问题:在计算机中,以1开头的就是补码的形式,是负数。

    ? ? ? 00000000 00000000 00000000 00000110 +6在计算机中表示方法
    0000000000 00000000 00000000 00000110 右移两位,正数补0,结果为1
    ----------------------------------------------------------------------------------------------

    ? ? 00000000 00000000 00000000 00000110 +6在计算机中表示方法
    11111111 11111111 11111111 11111001
    11111111 11111111 11111111 11111010 -6在计算机中的表示
    1111111111 11111111 11111111 11111010 右移两位,结果为负数
    1000000000 00000000 00000000 000001
    1000000000 00000000 00000000 000010 结果为-2
    这个地方很容易弄混,多想几次就会慢慢理解了。

    上面解释了带符号的移位操作,下面解释一下不带符号的移位操作

    无符号的移位只有右移,没有左移使用“>>>”进行移位,都补充0

    例如:
    public static void main(String[] args)
    {
    System.out.println(6>>>2);
    System.out.println(-6>>>2);
    }
    结果:

    1
    1073741822

    分析:

    ? ? 00000000 00000000 00000000 00000110 +6在计算机中表示方法
    0000000000 00000000 00000000 00000110 右移两位,正数补0,结果为1
    -----------------------------------------------------------------------------------------------------

    ? ? 00000000 00000000 00000000 00000110 +6在计算机中表示方法
    11111111 11111111 11111111 11111001
    11111111 11111111 11111111 11111010 -6在计算机中的表示
    0011111111 11111111 11111111 11111010 右移两位,补充0,结果为1073741822

    ?

    以下来自:http://jefflee.javaeye.com/blog/203863

    可以参考

    移位操作要注意的问题是高(低)位是补0还是补1和对char, byte, short型的操作:
    (1)<< : (left-shift), 最低位补0
    (2)>> : (signed right-shift), 右移过程使用符号位扩展(sign extension),即如果符号为为1则高位补1, 是0则补0,也就是逻辑右移
    (3)>>> : (unsigned right-shit),右移过程使用零扩展(zero extension),即最高位一律补0,也就是算术右移
    (4)移位操作的数据类型可以是byte, char, short, int, long型,但是对byte, char, short进行操作时会先把它们变成一个int型,最后得到一个int型的结果,对long型操作时得到一个long型结果,不可以对boolean型进行操作。
    (5)移位操作符可以和=合并起来,即 <<= 、 >>= 和 >>>=。例如 a >>= 2; 表示将a右移两位后的值重新赋给a。当时在使用这三个操作符对 byte, char, short型数据进行操作时要注意,例如有一下代码片段:


    public class ShiftTest
    {
    public static void main(String [] args)
    {
    byte a;
    byte b;
    byte c;
    a = 127;
    b = 127;
    c = 127;
    a <<= 2;
    System.out.println(a);
    System.out.println(b <<= 2);
    System.out.println(c << 2);
    }
    }

    运行结果是:
    -4
    -4
    508
    这说明了在操作a <<= 2 执行过程是这样的:先将 byte型的数 127变成int型,左移2位得到 508,然后把508赋给byte型变量a时只是简单地"折断"(truncate)得到数-4。编译时编译器不会提示你可能损失精度(实际上在本例中确实是损失精度了),但是如果你把a <<= 2改成 a = a << 2;编译器就会提示可能损失精度了。

    ?

    ================================================================================

    移位操作的简单计算方法

    >>右移操作

    x>>y

    就是x除以2的y此方,取整数

    <<左移操作

    X<<y

    就是x乘以2的y次方



    位逻辑运算符
    
        包括:
        & 与;| 或;~ 非(也叫做求反);^ 异或
    
        “& 与”、“| 或”、“~ 非”是基本逻辑运算,由此可以演变出“与非”、“或非”、“与或非”复合逻辑运算。“^ 异或”是一种特殊的逻辑运算,对它求反可以得到“同或”,所以“同或”逻辑也叫“异或非”逻辑。
    例子:
    5&3=1
    0000 0000 0000 0000 0000 0000 0000 0101
    0000 0000 0000 0000 0000 0000 0000 0011
    0000 0000 0000 0000 0000 0000 0000 0001
    
    -5&3=1
    1111 1111 1111 1111 1111 1111 1111 1011
    0000 0000 0000 0000 0000 0000 0000 0011
    0000 0000 0000 0000 0000 0000 0000 0011
    
    5|3=7
    0000 0000 0000 0000 0000 0000 0000 0101
    0000 0000 0000 0000 0000 0000 0000 0011
    0000 0000 0000 0000 0000 0000 0000 0111
     
  • 相关阅读:
    转载:【Oracle 集群】RAC知识图文详细教程(三)--RAC工作原理和相关组件
    转载:【Oracle 集群】RAC知识图文详细教程(一)--集群概念介绍
    转载:【Oracle 集群】RAC知识图文详细教程(二)--Oracle 集群概念及原理
    题目总结
    面试题(包含答案)
    ElementUI动态表格数据转换formatter
    父组件搜索列表 给 子组件传值问题
    项目提取公共接口方法
    数组常用方法总结
    vue全局注册
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3003136.html
Copyright © 2011-2022 走看看