Java移位运算

背景

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

推荐阅读更多精彩内容

  • 最近工作中被运算效率问题所困扰,比如大数据排序或者去重,因此现在需要补习一下位移运算。 首先讲一下位移概念? 左位...
    等一夏_81f7阅读 50评论 0 0
  • 移位运算符操作的对象就是二进制的位,可以单独用移位运算符来处理int型整数。有三种移位运算符 (<<,>>,>>>...
    MiaLing007阅读 56评论 0 0
  • 位运算符 位运算符主要针对两个二进制数的位进行逻辑运算,它包括:与(&)、或(|)、非(~)、异或(^)**运算规...
    深情不及酒伴阅读 235评论 0 1
  • 一、参考 1、java高级之java的左移运算符和右移运算符 二、简述 1、定义: 2、速度:机器码是二进制01运...
    Kandy_JS阅读 652评论 3 2
  • 在学习源码中,发现有大量使用位运算符,这样做的目的是为了节约内存开销和加快计算效率。 位运算符,这个"位"代表这什...
    杨杰C阅读 608评论 0 0