zoukankan      html  css  js  c++  java
  • 移位操作符

    移位操作符

    1. byte short char等类型变量进行移位前会先转换成int型
    2. long型转换前后皆为long型
    3. 移位操作符左边操作数为需要移位的操作数,右边为需要向左或向右移动的位数
    4. 移位操作符可与等号组合使用,表示先移位再赋值。eg.>>= 先移位再赋值给左边的变量

    分类

    1. 左移位操作符 << :向左移动,低位补0
    2. 有符号右移位操作符 >> :向右移动,负数高位补1,正数高位补0
    3. 无符号右移位操作符 >>>:向右移动,高位补0 (c++/c 中都没有)

    使用示例

    public class Main {
        public static void main(String[] args) {
            int i = 100;
            System.out.println(Integer.toBinaryString(i));
            System.out.println(Integer.toBinaryString(-i));
            System.out.println(Integer.toBinaryString(i << 4));
            System.out.println(Integer.toBinaryString(-i << 4));
            System.out.println(Integer.toBinaryString(i >> 4));
            System.out.println(Integer.toBinaryString(-i >> 4));
            System.out.println(Integer.toBinaryString(i >>> 4));
            System.out.println(Integer.toBinaryString(-i >>> 4));
        }
    }
    
    result:
    1100100
    11111111111111111111111110011100
    11001000000
    11111111111111111111100111000000
    110
    11111111111111111111111111111001
    110
    1111111111111111111111111001
    
    
    • Integer.toBinaryString(int i)方法是Integer类的静态方法,返回整型变量i的二进制表示字符串
    • 数据在计算机中以补码形式存在,正数补码是其本身,符号位为0,负数补码是其反码加一,符号位为1

    补充

    文章开头提到,1.byte short char等类型变量进行移位前会先转换成int型;3.移位操作符可与等号组合使用,表示先移位再赋值;两句话结合起来看的话,byte short char型变量在移位前会先进行类型转换,转换成int,这一步是没有问题的,因为我们知道扩展转换(从容纳数据量小的类型转换成容纳数据量大的类型)是安全的,然后进行移位赋值,在赋值的时候,同样需要进行类型转换,将移位后int型结果转换成原来的数据类型,而这一步是危险的,这是窄化转换(从容纳数据量大的类型转换成容纳数据量小的类型),因而有可能得到错误的结果。

    错误示例:

    public class Main {
        public static void main(String[] args) {
            int i = -1;
            System.out.println(Integer.toBinaryString(i));
            i >>>= 10;
            System.out.println(Integer.toBinaryString(i));
            short s = -1;
            System.out.println(Integer.toBinaryString(s));
            s >>>= 10;
            System.out.println(Integer.toBinaryString(s));
            byte b = -1;
            System.out.println(Integer.toBinaryString(b));
            b >>>= 10;
            System.out.println(Integer.toBinaryString(b));
        }
    }
    
    result:
    11111111111111111111111111111111
    1111111111111111111111
    11111111111111111111111111111111
    11111111111111111111111111111111
    11111111111111111111111111111111
    11111111111111111111111111111111
    

    要想得到正确的结果,可以向上一个例子一样,用println方法直接输出结果

    • 《Thinking in Java》中提到 只有数值右端的低5位才有用,这样可防止我们移位超过int型值所具有的位数
    • 因为int型占4字节,共32位,也就是说,一个操作数最多移动32位就毫无意义了,所以移位运算符右端的数字最大不能大于等于32位,即最大31,用二进制表示为11111,一个数的低五位即可表示。
    • 如果运算符右端的数字大于等于32,则可通过取32的模来得到真正需要移动的位数,eg. 1>>34,需要移动的位数34>32,因此让34对32取余,结果为34%32=2,因此真正的移位运算应该是1>>2
    • 同理long型占8字节,共64位,运算符右端数值的低6位对应的十进制才是有效移动位数

  • 相关阅读:
    使用eclipse创建Spring Boot项目
    Oracle 一个表的数据update到另一个表
    C3P0连接池属性配置注释
    Druid连接池
    Oracle 五笔码函数
    Oracle 拼音码函数
    JAVA JDK环境变量配置
    一 测试基础之测试方法
    SonarQube+Jenkins,搭建持续交付平台
    swagger集成到springBoot 项目中
  • 原文地址:https://www.cnblogs.com/skye-you/p/9588747.html
Copyright © 2011-2022 走看看