不该被忽视的CoreJava细节(三)

摘要:
很奇怪,Java有>>,但没有

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

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

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

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

二、移位运算案例

 1 /**
 2  *  Java移位运算:
 3  *  1)带符号左移 <<
 4  *  2)带符号右移 >>
 5  *  3)无符号右移 >>>
 6  *  
 7  *  注意点:
 8  *  1)本案例使用字面量10,默认为int型
 9  *  2)Java移位运算不支持小数
10  */
11 public class ShiftOperation {
12     public static void main(String[] args) {
13         // 正整数的带符号左移(0000_0000_0000_0000_0000_0000_0000_1010)B << 2
14         System.out.println(10 << 2);  // 40 
15         // 负整数的带符号左移  (1111_1111_1111_1111_1111_1111_1111_0110)B << 2
16         System.out.println(-10 << 2); // -40
17         
18         // 正整数的带符号右移(0000_0000_0000_0000_0000_0000_0000_1010)B >> 2
19         System.out.println(10 >> 2);  // 2
20         // 负整数的带符号右移  (1111_1111_1111_1111_1111_1111_1111_0110)B >> 2
21         System.out.println(-10 >> 2);  //-3
22         
23         // 正整数的带符号右移 (0000_0000_0000_0000_0000_0000_0000_1010)B >>> 2
24         System.out.println(10 >>> 2);  // 2
25         // 负整数的带符号右移 (1111_1111_1111_1111_1111_1111_1111_0110)B >>> 2
26         System.out.println(-10 >>> 2);    // 1073741821        
27     }
28 }

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

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

首先,问一个问题:为什么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类分析,尽请期待。

不该被忽视的CoreJava细节(三)第1张

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

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

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

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

免责声明:文章转载自《不该被忽视的CoreJava细节(三)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇windows下批量删除文件Android 4 学习(19):Services下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

(zxing.net)二维码Data Matrix的简介、实现与解码

一、简介 Data Matrix 二维条码原名Datacode,由美国国际资料公司(International Data Matrix, 简称ID Matrix)于1989年发明。Data-Matrix二维条码是一种矩阵式二维条码。 Data Matrix符号由规则排列的深浅色正方形模块构成,每个正方形模块就是一个基本单元,每个基本单元又被编码为一比特的数...

UVA 690 PipelineScheduling 位运算+dfs+剪枝

一开始最容易想到间隔最多为n,但是结点还是太多了,需要优化。 预处理:预判一下并保存下一个可以放的位置距离之前的距离。这样可以减少很多判断。 最优化剪枝:如果当前长度+剩下没放的程序*最短间隔如果大于等于ans,那么对答案没有贡献,可以剪去。 优化:占用和不占用两种状态,如果横向来看可以压缩为int,判断时用上为运算。 此题挂在长度的枚举上,我把长度为n给...

5.2Python数据处理篇之Sympy系列(二)---Sympy的基本操作

目录 目录 目录 前言 (一)符号的初始化与输出设置-symbol() symbols() latex() (1)说明: (2)源代码: (3)输出效果 1.作用: 2.操作: (二)替换符号-subs(old,new) (1)是否改变原表达式 (2)替换多个表达式 1.说明: 2.源代码: 3.输出效果: 4.注意点: (三)将字符串变为s...

汇编语言中的数据类型

目录 一、数制及相互转换 1. N 进制数转换为十进制数 2. 十进制数转换为 N 进制数 3. 二进制数转换为八进制数或十六进制数 4. 八进制数或十六进制数转换为二进制数 二、计算机中数和字符的表示 (一)计算机中数的表示方法 1. 原码表示法 2. 补码表示法 (二)二进制编码 1. 十进制数的二进制编码(BCD 码) 2. 字...

JavaScript位移运算多个大于号的使用方法

JavaScript中的无符号位移运算符是用三个大于号来表示的 计算方法 例 100>>>2 100的二进制是 01100100 向右移2位后为 00011001 最后结果为25 100>>>2==25 无符号位移(>>>)和有符号位移(>>)的区别是 有符号位移运算时如果数字为正数时位移后...

利用栈实现四则运算表达式求值----先将中缀表达式转换成后缀表达式,然后再求后缀表达式的值

利用栈实现四则运算表达式求值,附Python代码中缀表达式和后缀表达式 平时用到的标准的四则运算表达式就叫做中缀表达式,例如“9 +(3 - 1) * 3 + 10 / 2)”,特点是运算符在数字中间; 后缀表达式就是一种把运算符放在数字后面的形式,“9 3 1 - 3 * + 10 2 / +”即为上例中缀表达式对应的后缀表达式形式,后缀表达式还有一个特...