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次方
- 开发人员看测试之TDD和BDD
- AngularJS入门心得1——directive和controller如何通信
- AngularJS入门心得2——何为双向数据绑定
- AngularJS入门心得3——HTML的左右手指令
- AngularJS入门心得4——漫谈指令scope
- Enterprise Library深入解析与灵活应用(8):WCF与Exception Handling AppBlock集成[上]
- 苹果就“电池门”公开致歉;微信下拉任务栏新增小游戏;美团打车进入北京
- 新华三《中国城市数字经济指数白皮书》:深圳数字经济发展水平国内居首
- NodeMCU模块写入MicroPython固件
- 如何证明Application Domain的隔离性
- Enterprise Library深入解析与灵活应用(8):WCF与Exception Handling AppBlock集成[下]
- 我所理解的Remoting(1):Marshaling & Activation[上篇]
- oracle 12c 常见报告获取-AWR
- 人人公司收购美国卡车社区 Trucker Path,未来或探索无人驾驶
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- Sharding-JDBC 实现分库分表
- fastjson——使用 aop 打印入参,报错:getOutputStream() has already been called for this response
- webpack从零搭建开发环境
- 博客——使用 Redis 实现博客编辑的自动保存草稿功能
- linux下安装zabbix服务器shell脚本-添加主机-邮件监控报警zabbix-自动化运维
- Nginx——开启 GZIP 压缩
- 谈谈Vue.use的原理
- Nginx——ubuntu安装Nginx并配置https
- Istio 中业务开发需要关注的二三事
- MongoDB——Ubuntu安装及配置带认证的副本集(亲测)
- 经验——SpringBoot 获取 resource 目录下的文件
- 聚类热图怎么按自己的意愿调整分支的顺序?
- H5|HTTP-FLV|WS-FLV|HLS|RTMP免费直播点播播放器如何自定义层叠DIV全屏后显示在视频上方?
- 什么是时间分片(Time Slicing)?
- 48岁的C语言,你知道它背后的历史吗?