一、不该被遗忘的移位位运算

本文主要介绍移位运算(Shift Operation), 适当介绍一下其它相关的位运算。

甭说计算机刚发明那会,就连21世纪初那段日子,计算机内存都是KB/MB计算的。编写的程序需要充分考虑计算机的储存容量,好的程序必须是执行效率高,代码精炼,占用资源尽可能少,不容许任何的浪费。可想而知,那个时候位运算带来的运行性能上的提升和内存资源消耗降低是多么重要。

现如今计算机行业高速发展,位运算带来的高效率等优势已经被整体硬件水平的质变所冲淡,但是为什么我们还要学习掌握位运算呢?答案就两个字:装逼。这就像图形界面已经这么发达了,为什么我还是会用shell一样,无非就是显摆

二、移位运算案例

 /**
* Java移位运算:
* 1)带符号左移 <<
* 2)带符号右移 >>
* 3)无符号右移 >>>
*
* 注意点:
* 1)本案例使用字面量10,默认为int型
* 2)Java移位运算不支持小数
*/
public class ShiftOperation {
public static void main(String[] args) {
// 正整数的带符号左移(0000_0000_0000_0000_0000_0000_0000_1010)B << 2
System.out.println(10 << 2); // 40
// 负整数的带符号左移 (1111_1111_1111_1111_1111_1111_1111_0110)B << 2
System.out.println(-10 << 2); // -40 // 正整数的带符号右移(0000_0000_0000_0000_0000_0000_0000_1010)B >> 2
System.out.println(10 >> 2); // 2
// 负整数的带符号右移 (1111_1111_1111_1111_1111_1111_1111_0110)B >> 2
System.out.println(-10 >> 2); //-3 // 正整数的带符号右移 (0000_0000_0000_0000_0000_0000_0000_1010)B >>> 2
System.out.println(10 >>> 2); // 2
// 负整数的带符号右移 (1111_1111_1111_1111_1111_1111_1111_0110)B >>> 2
System.out.println(-10 >>> 2); // 1073741821
}
}

这些运算有人做过规律总结,甚至还有公式,但是我个人不推荐,记住了又能怎么样呢。任何东西,只要能从本质上理解,这就说明你已经完全掌握了,公式只不过为了应付考试而已,没有任何实际意义。

三、移位运算原理简单探究(参考教材学习)

首先,问一个问题:为什么Java移位运算没有无符号左移运算符(<<<)?

但凡非生活琐事,常问为什么对自身综合素质的提高大有裨益。这个问题近1年前我想过,今天也给大家分享一下。

1111_1111_1111_1111 << 2 结果:1111_1111_1111_1100
1111_1111_1111_1111 <<< 2 结果:1111_1111_1111_1100
结果完全相同,能少写一个<符号,何乐而不为呢 1111_1111_1111_1111 >> 2 结果:1111_1111_1111_111 负数带符号右移仍为负数
1111_1111_1111_1111 >>> 2 结果:0011_1111_1111_1111 负数无符号右移变成正数

说段题外话,十几天前,有同学晒了一张和众多书籍的合影,并说自己好像拥有好多知识。我回复了一条评论,有书籍并不代表有知识,有知识并不代表有文化,有文化并不代表有教养。其实,教育本身并不是等于教授知识,重要的是在于知识背后的思想。举些切合本节主题的例子,奥斯特发现电生磁,法拉第利用对称思想想到磁生电;麦克斯韦直到变电场可以产生变磁场,于是假设变磁场也可以激发变电场,于是有了电磁波的发现。

看到Java有>>>却没有<<<,这么奇怪,其实我们应该多去探究背后设计者是基于什么考虑的,或者你认为是基于什么考虑的。


移位运算的原理其实不难,真正略难的是从电路的角度来理解,在代码层次只要知道其运算规则即可。至少明确以下几点:

1)计算机中保存数据使用的是补码,正数的补码等于其原码、反码,负数的补码值上等于其反码加1。

2)原码和反码是非符号位按位取反。

3)正数符号位为0,负数符号位为1。

4)小数不能使用Java移位运算符进行运算。

5)带符号移位,左移右侧补0,右移左侧补符号位;无符号右移,左侧补0。

四、核心类库中移位运算案例

下面选择的是HashMap类中的一个方法。既有移位运算,又有异或运算,有兴趣的读者可以研究一下,今后会在集合框架专题中专门对HashMap类分析,尽请期待。

在Java源代码中大量用到了移位运算,比如二分搜索算法等等,应该引起注意。

五、简述Java中存在的位运算

Java位运算除了移位运算外,还有按位与(&)、按位或(|)、按位异或(^)、非(~)运算。能否运算符的有效使用,足够看出一个人的基本功。当然,如果要灵活运用这些操作符,需要对计算机底层有所了解,以及对操作符的运算性质了如指掌。

很多试题涉及到Java位运算符,今后都会以例题的形式展示给大家,然后慢慢的分析其中原理。

不该被忽视的CoreJava细节(三)的更多相关文章

  1. 不该被忽视的CoreJava细节(一)

    一.系列文章导言 <不该被忽视的CoreJava细节>系列文章将会持续更新.我希望自己通过这一系列文章的写作,能与读者一起进步,逐步完善对Java体系结构的了解. 二.本期关注点 几乎翻看 ...

  2. 不该被忽视的CoreJava细节(四)

    令人纳闷的数组初始化细节 这个细节问题我很久以前就想深入研究一下,但是一直没有能够抽出时间,借这系列文章的东风,尽量解决掉这个"心头病". 下面以一维int数组为例,对数组初始化方 ...

  3. ASP.NET常被忽视的一些细节

    原文:ASP.NET常被忽视的一些细节 前段时间碰到一个问题:为什么在ASP.NET程序中定时器有时候会不工作? 这个问题看起来很奇怪,代码好像也没错,但就是结果与预期不一致. 其实这里是ASP.NE ...

  4. mysql.user细节三问

    一.如何拒绝用户从某个精确ip访问数据库假如在mysql.user表中存在用户'mydba'@'192.168.85.%',现在想拒绝此用户从某个精确ip访问数据库 # 创建精确ip用户,分配不同的密 ...

  5. C语言里面关于数组的一个容易忽视的小细节

    ginobili@VM_44_28_sles10sp1:~/code> cat test3.cpp #include <stdio.h> int main(){ char a[5] ...

  6. 谈谈一些有趣的CSS题目(三)-- 层叠顺序与堆栈上下文知多少

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  7. 【原创】构建高性能ASP.NET站点之三 细节决定成败

    原文:[原创]构建高性能ASP.NET站点之三 细节决定成败 构建高性能ASP.NET站点之三 细节决定成败 前言:曾经就因为一个小小的疏忽,从而导致了服务器崩溃了,后来才发现:原来就是因为一个循环而 ...

  8. java三种工厂模式

    适用场合: 7.3 工厂模式的适用场合 创建新对象最简单的办法是使用new关键字和具体类.只有在某些场合下,创建和维护对象工厂所带来的额外复杂性才是物有所值.本节概括了这些场合. 7.3.1 动态实现 ...

  9. 20155334 2016-2017-2 《Java程序设计》第三周学习总结

    20155334 2016-2017-2 <Java程序设计>第三周学习总结 教材学习内容总结 第四章: 讲的是类类型,使用java撰写程序几乎都在使用对象(Object),要产生对象必须 ...

随机推荐

  1. 由count(sno)和count(cno)引发的思考

    最近在练习sql语句,在一个select查询语句上有理解性偏差,现整理汇总下相关知识点. 首先,说下这个问题吧. 问题是:查询选课人数大于等于2人的课程编号以及选课的人数 具体的表结构信息: 我自己的 ...

  2. .Net开发中的@ 和 using 使用技巧

    一.@符号的妙用 1.可以作为保留关键字的标识符 C#规范当中,不允许使用保留关键字(class.bool等)当作普通的标识符来命名,这时候@符号作用就体现 出来了,可以通过@符号前缀把这些保留关键字 ...

  3. [转]centos7.2 下 nginx 开机启动

    1.在系统服务目录里创建nginx.service文件 vi /lib/systemd/system/nginx.service 内容如下 [Unit] Description=nginx After ...

  4. GoWeb开发_Iris框架讲解(二):Get、Post、Put等请求及数据返回格式

    数据请求方式的分类 所有的项目中使用的请求都遵循HTTP协议标准,HTTP协议经过了1.0和1.1两个版本的发展. HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法. HTTP ...

  5. 从零开始安装 Ambari (1) -- 安装前的准备工作

    Ambari 没有简单的 .tar.gz 结尾的包(反正我找到).apache 官网提供的安装方法,是要下载源码,自己编译成安装包安装.说明文档还不够细.编译的时候是用 maven,照理来说不应该会失 ...

  6. 【转】processOnServer

    源地址:http://blog.csdn.net/dl020840504/article/details/8856853

  7. Maven下把父项目下的子项目导出到myeclipse中

    第一种在父项目下已有子项目:右击空白------import 第二步Maven4MyEclipse-----------Existing  Maven  Projects 第三部选择父项目下面的子项目 ...

  8. springcloud中常用的注解@

    @SpringBootApplication是springboot启动类,包括三个注解,他们的作用分别是: @Configuration:表示将该类作用springboot配置文件类 @EnableA ...

  9. 01.Spring Ioc 容器

    基本概念 Spring 的 Ioc 容器,通常也称应用上下文.它包含了两个概念 Ioc 和 容器: 容器:顾名思义就是用来装东西的,在 Spring 中容器里盛放的就是各种各样的 Bean.既然装了东 ...

  10. 非关系型数据库---Memcached

    一.概述 1.Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载: 2.Memcached通过 在内存中缓存对象和数据 来减少读取数据库的次数,从而提升网站的 ...