java左移右移运算符详解
在阅读源码的过程中,经常会看到这些符号<< ,>>,>>>,这些符号在Java中叫移位运算符,在写代码的过程中,虽然我们基本上不会去写这些符号,但需要明白这些符号的运算原理,比如HashMap中有以下代码:
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;//左移
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);//无符号右移
}
上段代码中就包含左移运算符<<,无符号右移运算符>>>。这篇文章详细说一下这三个符号:
1、左移运算符:<<
先随便定义一个int类型的数int,十进制的value = 733183670,转换成二进制在计算机中的表示如下:

value << 1,左移1位

左移1位后换算成十进制的值为:1466367340,刚好是733183670的两倍, 有些人在乘2操作时喜欢用左移运算符来替代。
value << 8,左移8位看一下:

左移8位后变成了十进制的值为:-1283541504,移动8位后,由于首位变成了1,也就是说成了负数,在使用中要考虑变成负数的情况。
根据这个规则,左移32位后,右边补上32个0值是不是就变成了十进制的0了?答案是NO,当int类型进行左移操作时,左移位数大于等于32位操作时,会先求余(%)后再进行左移操作。也就是说左移32位相当于不进行移位操作,左移40位相当于左移8位(40%32=8)。当long类型进行左移操作时,long类型在二进制中的体现是64位的,因此求余操作的基数也变成了64,也就是说左移64位相当于没有移位,左移72位相当于左移8位(72%64=8),写一段代码来测试一下
int intValue = 733183670;//随意写一个数
System.out.println("intValue:" + (intValue));//打印intValue
System.out.println("intValue左移1位:" + (intValue << 1));//左移1位
System.out.println("intValue左移8位:" + (intValue << 8));//左移8位
//当int类型左移位数大于等于32位操作时,会先求余后再进行移位操作
System.out.println("intValue左移32位:" + (intValue << 32));//求余为32%32=0,相当于左移0位(不移位)
System.out.println("intValue左移40位:" + (intValue << 40));//求余为40%32=8,相当于左移8位
System.out.println("intValue左移64位:" + (intValue << 64));//求余为64%32=0,相当于左移0位(不移位)
long longValue = 733183670L;
System.out.println("longValue:" + (longValue));//打印longValue
System.out.println("longValue左移1位:" + (longValue << 1));//左移1位
System.out.println("longValue左移8位:" + (longValue << 8));//左移8位
//当long类型左移位数大于等于64位操作时,会先求余后再进行移位操作
System.out.println("longValue左移64位:" + (longValue << 64));//求余为64%64=0,相当于左移0位(不移位)
System.out.println("longValue左移72位:" + (longValue << 72));//求余为72%64=8,相当于左移8位
System.out.println("longValue左移128位:" + (longValue << 128));//求余为128%64=0,相当于左移0位(不移位)
看一下结果:

由于double,float在二进制中的表现比较特殊,因此不能来进行移位操作,报错,编译不过,如下图:

注意:其它几种整形byte,short移位前会先转换为int类型(32位)再进行移位,这里就不写代码测试了,大家有兴趣可自行测试。
综上所述:左移 << 其实很简单,也就是说丢弃左边指定位数,右边补0。
2、右移运算符:>>
还是这个数:733183670

value >> 1,右移1位

右移1位后换算成十进制的值为:366591835,刚好是733183670的1半, 有些人在除2操作时喜欢用右移运算符来替代
value >> 8,右移8位看一下

写一段代码测试一下
int intValue = 733183670;//随意写一个数
System.out.println("intValue:" + (intValue));//打印intValue
System.out.println("intValue右移1位:" + (intValue >> 1));//右移1位
System.out.println("intValue右移8位:" + (intValue >> 8));//右移8位
//当int类型右移位数大于等于32位操作时,会先求余后再进行移位操作
System.out.println("intValue右移32位:" + (intValue >> 32));//求余为32%32=0,相当于右移0位(不移位)
System.out.println("intValue右移40位:" + (intValue >> 40));//求余为40%32=8,相当于右移8位
System.out.println("intValue右移64位:" + (intValue >> 64));//求余为64%32=0,相当于右移0位(不移位)
long longValue = 733183670L;
System.out.println("longValue:" + (longValue));//打印longValue
System.out.println("longValue右移1位:" + (longValue >> 1));//右移1位
System.out.println("longValue右移8位:" + (longValue >> 8));//右移8位
//当long类型右移位数大于等于64位操作时,会先求余后再进行移位操作
System.out.println("longValue右移64位:" + (longValue >> 64));//求余为64%64=0,相当于右移0位(不移位)
System.out.println("longValue右移72位:" + (longValue >> 72));//求余为72%64=8,相当于右移8位
System.out.println("longValue右移128位:" + (longValue >> 128));//求余为128%64=0,相当于右移0位(不移位)
结果:

和左移一样,int类型移位大于等于32位时,long类型大于等于64位时,会先做求余处理再位移处理,byte,short移位前会先转换为int类型(32位)再进行移位。以上是正数的位移,我们再来看看负数的右移运算,如图,负数intValue:-733183670的二进制表现如下图:

右移8位,intValue >> 8

综上所述:右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上符号位。
3、无符号右移运算符:>>>
无符号右移运算符>>>和右移运算符>>是一样的,只不过右移时左边是补上符号位,而无符号右移运算符是补上0,也就是说,对于正数移位来说等同于:>>,负数通过此移位运算符能移位成正数。以-733183670>>>8为例来画一下图

无符号右移运算符>>的运算规则也很简单,丢弃右边指定位数,左边补上0。
摘自https://zhuanlan.zhihu.com/p/30108890
java左移右移运算符详解的更多相关文章
- Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)
位运算符主要针对二进制,它包括了:“与”.“非”.“或”.“异或”.从表面上看似乎有点像逻辑运算符,但逻辑运算符是针对两个关系运算符来进行逻辑运算,而位运算符主要针对两个二进制数的位进行逻辑运算.下面 ...
- Java:Java的<<<移位运算符详解
1) 左移运算(<<) 左移就是把所有位向左移动几位 如: 12 << 2 意思就是12向左移动两位 12的二进制是: 0000 1100 通过这个图我们 ...
- java左移右移运算符
http://blog.csdn.net/dandanteng/article/details/7433531 首先要明白一点,这里面所有的操作都是针对存储在计算机中中二进制的操作,那么就要知道,正数 ...
- Java基础之 数组详解
前言:Java内功心法之数组详解,看完这篇你向Java大神的路上又迈出了一步(有什么问题或者需要资料可以联系我的扣扣:734999078) 数组概念 同一种类型数据的集合.其实数组就是一个容器. 数组 ...
- Net is as typeof 运行运算符详解 net 自定义泛型那点事
Net is as typeof 运行运算符详解 概述 在了解运行运算符的前提我们需要了解什么是RTTI ,在任何一门面向对象的语言中,都有RTTI这个概念(即 运行时). RTTI(Run-Ti ...
- Java 8 Stream API详解--转
原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...
- java反射机制深入详解
java反射机制深入详解 转自:http://www.cnblogs.com/hxsyl/archive/2013/03/23/2977593.html 一.概念 反射就是把Java的各种成分映射成 ...
- 国际化,java.util.ResourceBundle使用详解
java.util.ResourceBundle使用详解 一.认识国际化资源文件 这个类提供软件国际化的捷径.通过此类,可以使您所编写的程序可以: 轻松地本地化或翻译成不同的 ...
- java之StringBuffer类详解
StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...
随机推荐
- Redis/Mysql/SQLite/MongoDB 数据库对比
一.Redis: redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(so ...
- 初学者刚学c++在定义类时只有成员变量易犯的错误
------------------------ #include<iostream> using namespace std;//c++的命名空间 class circle { publ ...
- 第7.22节 Python中使用super调用父类的方法
第7.22节 Python中使用super调用父类的方法 前面章节很多地方都引入了super方法,这个方法就是访问超类这个类对象的.由于super方法的特殊性,本节单独谈一谈super方法. 一.su ...
- 第11.14节 正则表达式转义符和Python转义符相同引发问题的解决办法
正则表达式使用反斜杠('\')来把特殊字符转义成普通字符(为了方便称为"正则表达式转义"),而反斜杠在普通的 Python 字符串里也是转义符(称为"字符串转义" ...
- PyQt(Python+Qt)学习随笔:QListWidget获取当前选中项的selectedItems方法
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QListWidget的selectedItems方法返回列表部件中所有选中项的一个列表,调用语法如 ...
- Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.
用pycharm连接mysql报错 改变serverTimezone 改了之后确实可以连接上mysql数据库
- 团队作业6(A)-Alpha阶段项目复审
Alpha阶段项目复审 复审团队: 莫政 (3118005067). 卢耀恒(3118005065) . 许梓莹(3218005083). 梁小燕(3218005081).高嘉淳(3118005047 ...
- js中单引号和双引号区别
总结: 1.无论单引号还是双引号都是成双成对出现的,否则报错!浏览器在读到第一个双引号开始,第二个双引号结束,同样浏览器读取单引号也是第一个开始,第二个单引号结束,在使用的时候必须遵循规则那就是一对双 ...
- Springboot mini - Solon详解(四)- Solon的事务传播机制
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- python魔术方法总结
获取属性 __ getattr __(self, name) 定义当用户试图获取一个不存在的属性时的行为 __ getattribute __(self, name) 定义当该类的属性被访问时的行为 ...