温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java位运算的基础知识有哪些

发布时间:2021-11-19 16:37:33 来源:亿速云 阅读:132 作者:iii 栏目:编程语言

这篇文章主要讲解了“java位运算的基础知识有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java位运算的基础知识有哪些”吧!

一切的起源:二进制

位:二进制位,简称“位”。是二进制记数系统中表示小于2的整数的符号,一般用1或 0表示,是具有相等概率的两种状态中的一种。二进制位的位数可表示一个机器字的字长,一个二进制位包含的信息量称为一比特(bit)。

举个栗子:int占4个字节(byte)1byte = 8bit换算下来,一个int类型即占32bitint i = 88; 这里的88为十进制,转换为二进制为:1011000,使用完整的32位表示即为:00000000 00000000 00000000 01011000

上文中的00000000 00000000 0000000001011000即为十进制88转为二进制的 原码 ,与其相关的定义还有 反码 补码

关于原码、反码和补码

在计算机内,有符号数有三种表示法:原码、反码以及补码。原码:就是二进制定点表示法,即最高位为符号位,“0”正负“1”,其余位表示数值的大小。反码:正数的反码与其原码相同;负数的反码是对正数逐位取反,符号位保持为1。补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。

同样的,我们使用 “88” 举例说明原码、反码以及补码。

“88”的原码:00000000 00000000 00000000 01011000“88”的反码:00000000 00000000 00000000 01011000“88”的补码:00000000 00000000 00000000 01011000

对于负数 “-88”,其原码、反码以及补码如下:

“-88”的原码:10000000 00000000 00000000 01011000“-88”的反码:11111111 11111111 11111111 10100111“-88”的补码:11111111 11111111 11111111 10101000

为什么要使用补码?

简单来说,就是计算机计算减法时有各种不方便,于是发明了反码,结果发现反码也有缺陷(有两个零存在:“+0”和“-0”),进而发明了补码解决这个问题。

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

有关补码的意义及作用在上面的链接里讨论的非常详尽,我这里就不班门弄斧了,理解就好~

对原码、反码以及补码有一个初步的认知后,我们接下来再看位运算就会清晰很多。

关于位运算

关于位运算,这里运用哲学上三个究极问题试图讲解清楚位运算究竟是何方神圣:什么是位运算?位运算的作用?位运算有什么优势?

什么是位运算

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算就是直接对整数在内存中的二进制位进行操作。比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。

下表列出了位运算符的基本运算(A = 8, B = 9)

按位与&      如果相对应位都是1,则结果为1,否则为0      A&B=8,即1000              按位或|      如果相对应位都是0,则结果为0,否则为1      A|B=9,即1001              按位异或^      如果相对应位值相同,则结果为0,否则为1      A^B=1,即0001              按位取反~      按位取反运算符翻转操作数的每一位,即0变成1,1变成0      ~A=7,即0111              左移 <<      按位左移运算符。左操作数按位左移右操作数指定的位数      A << 2 = 32,即1000 00              右移 >>      按位右移运算符。左操作数按位右移右操作数指定的位数      A >> 2 = 2,即0010

位运算的作用及优势

我尝试脱离实际应用场景描述清楚位运算的作用及优势,然后发现脱离实际讲应用是件非常困难的事情,其难度不亚于买彩票。所以这里结合Android原码中的MeasureSpec类来描述位运算的作用和优势。熟悉Android View体系的小伙伴应该都对MeasureSpec不陌生。不熟悉的请自行Google,不然下面你看起来可能就会有些云里雾里。我们来看它的代码:

public static class MeasureSpec {private static final int MODE_SHIFT = 30;private static final int MODE_MASK = 0x3 << MODE_SHIFT;public static final int UNSPECIFIED = 0 << MODE_SHIFT;public static final int EXACTLY = 1 << MODE_SHIFT;public static final int AT_MOST = 2 << MODE_SHIFT;public static int makeMeasureSpec(int size, int mode) {if (sUseBrokenMakeMeasureSpec) {return size + mode;} else {return (size & ~MODE_MASK) | (mode & MODE_MASK);}}public static int getMode(int measureSpec) {return (measureSpec & MODE_MASK);}public static int getSize(int measureSpec) {return (measureSpec & ~MODE_MASK);}}

操作符描述例子

代码不难理解,上面就运用了很多位运算。我们都知道MeasureSpec是用来操作View的测量模式以及测量大小的。这个测量模式和测量大小在系统中使用一个32位的int类型的参数表示。如果让我们自己去实现这样一个操作测量模式和测量大小的类,我们大概会这么写:

public class MeasureSpec{public static final int UNSPECIFIED = 0;public static final int EXACTLY = 1;public static final int AT_MOST = 2;/*** 测量模式*/private int mode;/*** 测量大小*/private int size;public int getMode() {return mode;}public void setMode(int mode) {this.mode = mode;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}}

然后每次对View进行操作的时候都会 new 一个MeasureSpec对象,对其的mode和size参数进行相应的操作。

这里原码就很巧妙的运用了位运算简化了相应的操作,使用32位的二进制来操作mode和size:高两位表示mode,低30位表示size,避免了频繁的创建对象,更省内存,让我等对位运算不了解的拍手称秒哇。

感谢各位的阅读,以上就是“java位运算的基础知识有哪些”的内容了,经过本文的学习后,相信大家对java位运算的基础知识有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI