首页 > 编程知识 正文

java位运算符详解,java中的位运算符

时间:2023-05-03 17:53:06 阅读:179408 作者:951

最近又回去重新看了java的基础书籍。 在总结记录之前有一个容易混淆的知识点。 接下来是本篇要记录的内容

一.相关基础概念

在开始了解java位运算的知识之前,让我们先了解一些基本的概念、机器数量、真值、源代码、反码和补充码。

1 .机器数量

我们知道代码和数值最后都以二进制形式存在于计算机中,但一个数值在计算机中的二进制表示形式就是该数的机器数。 机器数量有符号位,计算机用二进制的最高有效位存储符号。 正数为0,负数为1,如下例(

十进制5、计算机字长8位,其二进制为00000101

十进制的-5,计算机的字长为8位,其二进制是10000101。 (这里使用的是原代码。

其中00000101和10000101是机器数量

2 .真值

机器数量的第1位为符号位,因此其型号值不等于其真值的数值。 也就是说,10000101表示的是-5而不是133。 (10000101的十进制数为131,假设最高有效位不是符号位。 )-5才是机器数量的真正值。

3 .源代码

源代码是计算机中数字的二进制点表示方法。 原符号表示法是在数值前追加符号位(即最高位为符号位)的方法。 正数表示该位为0,负数表示该位为1,剩下的位表示数值的大小。

[ 5]=[00000101] (源代码)

[ - 5]=[10000101] (源代码)

由于第一位是符号位,因此8位二进制值的范围为[ 1111111,01111111 ]或[-127,127 ]

4 .反码

反码是数值存储的一种,但补数为了更有效地表达计算机中的数字形式,大多数计算机不采用反码表示数。 逆符号表示方法为以下的:

正数的反码就是本身

负数的逆符号基于其原始符号,符号的比特不变,而剩馀的各个比特取逆

[ 5]=[00000101] (原始代码)=[00000101] (反向代码)

[ - 5]=[10000101] (原始代码=[11111010] (反向代码) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )。

5 .补数

在计算机系统中,数值都用补码表示和存储。 这是因为,通过使用补数,能够将编码比特和数值字段统一地处理; 同时,加法和减法也可以统一处理。 补数的表示方法为:

正数的补数就是本身

负数的补数,基于原来的符号,符号的位数不变,剩下的各位取反,最后1.(即根据反码为1 ) )。

[ 5]==[00000101] (原始代码) ([00000101] (反向代码) ) ) 0000101 ) (辅助代码) ) )。

[ - 5]=[10000101] (原代码((11111010 ) (反码) ) (11111011 ) (辅助代码) ) ) ) ) )。

6 .总结

计算机中的符号数有原代码、反代码、补充代码三种表示方法。 三种显示方法都有两个部分:已编码比特和数字比特,已编码比特都由0表示“正”,由1表示“负”,并且数字比特的三种显示方法彼此不同。 在计算机系统中,数值总是用补码表示和存储。

二. Java位运算

移位操作: (只对int型数据有效。 在java中,一个int的长度始终为32位,也就是4个字节,用于操作该整数的二进制数。 )也可用于byte、short、char、long )的类型。 这些都是整数的形式。 对于这四种类型,JVM将它们转换为int类型,然后进行操作。

7 .左移() )。

mn的含义使用:整数m表示的二进制数向左位移n个比特,即使使高位位移n个比特也要舍弃,补充低位0.030。 (在这种情况下,正数可能为负数) )以下示例:

52 )将十进制数值5左移两位,按以下步骤计算:

将5位转换为16位的二进制机器数: 000000000000000000000000000000001

根据左移原理,将二进制数左移两位。 0000000000000000000000000000000000000000001000

向左移动的话结果会是20

529:将十进制数值5向左偏移29位,按以下顺序计算,

将5位转换为16位的二进制机器数: 000000000000000000000000000000001

根据左移原理,将二进制数左移29位。 1010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

左移则高位为1,结果明显为负

总结:在mn即数字不溢出的前提下,对于正数和负数,左移n个比特都相当于m乘以2的n次幂。

8 .向右移动() )。

mn的含义将:整数m表示的二进制数向右位移n个比特,m是正数,高位都补0; m是负数,高位都补1。 例子如下。

52 )将十进制数值5右移两位,按照以下步骤计算,

5位16位二进制计算机数: 00

000000 00000000 00000000 00000101

按右移原理,将二进制数左移两位:00000000 00000000 00000000 00000001

右移后结果为1

-5>>2:把十进制的数值-5右移两位,按如下步骤计算,

把-5转位16位的二进制机器数:11111111 11111111 11111111 11111011

按右移原理,将二进制数右移两位:11111111 11111111 11111111 11111110

右移后结果为-2

小结:

 m>>n即相当于m除以2的n次方,得到的为整数时,即为结果。如果结果为小数,此时会出现两种情况:

如果m为正数,得到的商会无条件 的舍弃小数位;

如果m为负数,舍弃小数部分,然后把整数部分加+1得到位移后的值。

9.无符号右移(>>>)

m>>>n:整数m表示的二进制右移n位,不论正负数,高位都补0,实例如下:

5>>>2 :把十进制的数值5右移两位,按如下步骤计算,

把5转位16位的二进制机器数:00000000 00000000 00000000 00000101

按右移原理,将二进制数左移两位:00000000 00000000 00000000 00000001

右移后结果为1

-5>>>2:把十进制的数值-5右移两位,按如下步骤计算,

把-5转位16位的二进制机器数:11111111 11111111 11111111 11111011

按右移原理,将二进制数右移两位:00111111 11111111 11111111 11111110

右移后结果为正数

10.按位非操作(~)

~ 按位取反操作符,对每个二进制位的内容求反,即1变成0,0变成1实例如下

把-5转位16位的二进制机器数:11111111 11111111 11111111 11111011

~(-5) 取反结果:00000000 00000000 00000000 00000100 

转为十进制,结果为4

11.按位与操作(&)

& 位与操作符,对应的二进制位进行与操作,两个都为1才为1,其他情况均为0,原理如下:

1&0=0

0&0=0

1&1=1

0&1=0

实例:-5 & 4

-5的二进制形式为: 11111111 11111111 11111111 11111011

 4的二进制形式为:  00000000 00000000 00000000 00000100

——————————————————————————————

逻辑与运算结果:     00000000 00000000 00000000 00000000

最终结果为0。

12.按位或操作(|)

| 位或操作符,对应的二进制位进行或操作,两个都为0才为0,其他情况均为1,原理如下:

1|0=1

0|0=0

1|1=1

0|1=1

实例:-5 | 4

 -5的二进制形式为:11111111 11111111 11111111 11111011

  4的二进制形式为:00000000 00000000 00000000 00000100

————————————————————————————

逻辑或运算结果:    11111111 11111111 11111111 11111111

最终结果为-1。

利用或的原理我们可以把字节转换为整数,-64&0xFF=192,其中0xFF表示整数255。

13.按位异或操作( ^ )

^ 异或操作符,相同位值为0 否则为1,原理如下:

1^1=0

1^0=1

0^1=1

0^0=0

实例:-5 ^  4

 -5的二进制形式为:11111111 11111111 11111111 11111011

  4的二进制形式为:00000000 00000000 00000000 00000100

————————————————————————————

逻辑异或运算结果:    11111111 11111111 11111111 11111111

最终结果为-1。

其实利用逻辑异或操作有个作用就是可以比较两个数值是否相等,即利用1^1=0,0^0=0的原理,如5^5==0。

14.总结

通过上面的分析,我们对java的位运算也算有了比较全面的了解,那么我们的程序通过位运算又有什么优势呢?其实通过位运算确实会比我们直接的程序代码运算会快很多,因为位运算直接运算的是计算机底层的二进制机器操作指令,而我们的程序代码运算最终也是要转成计算机可识别的二进制操作指令才能执行,位运算可以理解为省了中间转换的操作,处理器可以直接操作。事实是我们在某些源码经常能看见如下代码:

<span style="font-family:Microsoft YaHei;"> public static final int OP_CONNECT = 1 << 3; /** * Operation-set bit for socket-accept operations. </p> * * <p> Suppose that a selection key's interest set contains * <tt>OP_ACCEPT</tt> at the start of a <a * rel="external nofollow" href="Selector.html#selop">selection operation</a>. If the selector * detects that the corresponding server-socket channel is ready to accept * another connection, or has an error pending, then it will add * <tt>OP_ACCEPT</tt> to the key's ready set and add the key to its * selected-key set. </p> */ public static final int OP_ACCEPT = 1 << 4;</span>其实原理是一样的,处理器能够直接支持和处理。


参考内容:

http://www.cnblogs.com/dongpo888/archive/2011/07/13/2105001.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。