Java移位运算

作者: 风清袖一 | 来源:发表于2019-01-04 17:51 被阅读16次

    背景

    java或android源码中经常会使用移位运算来代替乘除运算,因为移位运算的性能比乘除运算的高(PS:对于计算机而言,移位运算只是移了个位置),所以了解移位运算的计算过程对于我们阅读源码会有一定的帮助。

    原码、反码、补码

    原码是人脑最容易理解和计算的表示方式

    第一位表示符号, 其余位表示值

    -1的原码是10000000 00000000 00000000 00000001

    反码是人脑无法直观看出其数值的. 通常需要转换成原码在计算其数值

    正数的反码是其本身

    负数的反码是在其原码的基础上, 符号位不变,其余各个位取反

    -1的反码是11111111 11111111 11111111 11111110

    补码是人脑无法直观看出其数值的. 通常需要转换成原码在计算其数值

    正数的补码就是其本身

    负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

    -1的补码是11111111 11111111 11111111 11111111

    左移运算符:<<

    System.out.println(1<<1); // 2
    System.out.println(1<<32); // 1
    System.out.println(-1<<1); // -2
    System.out.println(-1<<32); // -1
    

    结论:丢弃左边指定位数,右边补0

    右移运算符:>>

    System.out.println(1>>1); // 0
    System.out.println(1>>32); // 1
    System.out.println(-1>>1); // -1,因为-1的二进制反码是11111111 11111111 11111111 11111111
    System.out.println(-1>>32); // -1
    

    结论:丢弃右边指定位数,左边补上符号位

    无符号右移运算符:>>>

    System.out.println(1>>>1); // 0
    System.out.println(1>>>32); // 1
    System.out.println(-1>>>1); // 2147483647
    System.out.println(-1>>>32); // -1,这里仍然是-1,是因为int类型是32位,32%32=0,所以实际上并没有发生移位
    

    结论:丢弃右边指定位数,左边补上0

    结论

    对于机器而言,java中的移位运算都是对补码执行移位运算的,下面以-1<<1=-2为例进行讲解:

    1. -1的原码:10000000 00000000 00000000 00000001
    2. -1的反码:11111111 11111111 11111111 11111110
    3. -1的补码:11111111 11111111 11111111 11111111
    4. 执行移位操作
    5. -1移位后的补码:11111111 11111111 11111111 11111110
    6. -1移位后的反码:11111111 11111111 11111111 11111101
    7. -1移位后的原码:10000000 00000000 00000000 00000010
    8. 得到最后的原码十进制值为-2

    相关文章

      网友评论

        本文标题:Java移位运算

        本文链接:https://www.haomeiwen.com/subject/lnukrqtx.html