java 位运算解析

在实际开发中我们一般不常用到java的位运算,但有时去看java的一些源码又经常会看到这些位运算符,所以有必要了解一下位运算,同时位运算的使用对运算效率会有一定的提升,特别是高重复运算,会节约相当的时间开支。

Java位运算符列表如下:
& 同为1则为1,其余为0
| 一个为1则为1,否则为0
^ 异或相同为0,不同为1
~为1则为0,为0则为1
<< 左位移 将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)
>> 右位移将运算符左边的运算对象向右移动运算符右侧指定的位数。 “有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。
>>> 无符号右移无论正负,都在高位插入0

在了解位运算之前,先要了解一下二进制的一些表示方法,这里使用的是java语言(注意:在java中是不允许二进制表示的,允许八进制和十六进制)。
Java整型数据类型有:byte、char、short、int、long。要把它们转换成二进制的原码形式,必须明白他们各占几个字节(一个字节占8位)。

数据类型所占位数
byte8
boolean8
short16
int 32
long64
float32
double64
char16

另外二进制中只有0和1,所以正负不是用+ -加减号来表示,而是用最高位数字来表示,0表示正,1表示负,来看两个例子:

System.out.println(Integer.toBinaryString(10)); //打印结果:1010  
System.out.println(Integer.toBinaryString(-10)); //打印结果:11111111111111111111111111110110 

对于正数的转换比较简单,比如上面的10,转换二进制后是00000000000000000000000000001010。
但对于负数的转换稍麻烦,转换过程如下:
00000000000000000000000000001010 //取绝对值(10),转换二进制
11111111111111111111111111110101 //取反(反码)
11111111111111111111111111110110 //反码基础上+1(补码)
(一) 接下来再看具体的位运算:

& 按位与:
举例一:

System.out.println(5&6); //打印结果:4  

运算过程:

00000000000000000000000000000101 //5转换二进制

00000000000000000000000000000110 //6转换二进制

00000000000000000000000000000110 //同为1为1,否则为0的原则

4 //转换十进制,结果为4
举例二:

System.out.println(-5&6); //打印结果:2 

运算过程:

11111111111111111111111111111011 //-5转二进制

00000000000000000000000000000110 //6转二进制

00000000000000000000000000000010 //同为1为1,否则为0的原则

2 //转十进制,结果为2

| 按位或:

举例一:

System.out.println(-5|-6); //打印结果:-5 

运算过程:

11111111111111111111111111111011 //-5转二进制

11111111111111111111111111111010 //-6转二进制

11111111111111111111111111111011 //一个为1则为1的原则

-5 //转十进制,结果为-5

~ 按位非:

举例一:

System.out.println(~-5); //打印结果:4 

运算过程:

11111111111111111111111111111011 //-5转二进制

00000000000000000000000000000100 //1为0,0为1原则

4 //转换十进制,结果为4

^ 按位异或

举例一:

System.out.println(2^3); //打印结果:1  

运算过程:

00000000000000000000000000000010 //2转二进制

00000000000000000000000000000011 //3转二进制

00000000000000000000000000000001 //相同为0,不同为1

1 //转换为十进制,结果为1

<< 左位移

举例一:

System.out.println(5<<3); //打印结果40  

运算过程:

00000000000000000000000000000101 //5转二进制

00000000000000000000000000101000 //左移三位,低位补0

40 //转十进制,结果为40

>> 右位移

举例一:

System.out.println(5>>2);  //打印结果1  

运算过程:

00000000000000000000000000000101 //5转二进制

00000000000000000000000000000001 //右移两位,高位补0(补符号位数值,正补0,负补1)

举例二:

System.out.println(-5>>2); //打印结果-2  

运算过程:

11111111111111111111111111111011 //-5转二进制

11111111111111111111111111111110 //右移两位,高位补1(补符号位数值,正补0,负补1)

>>> 无符号右移

举例一:

System.out.println(-5>>>2); //打印结果是1073741822 

运算过程:

11111111111111111111111111111011 //-5转二进制

00111111111111111111111111111110 //右移两位,高位补0(与符号位无关,统一补0)

写到这里,再回头看为什么会有位运算呢,仔细研究便会发现一些奥妙之处,比如:

System.out.println(2<<2); //打印结果8  
System.out.println(2<<3); //打印结果16  
System.out.println(2<<4); //打印结果32 

有没有发现什么不一样的地方? 推算得出以下公式:Y << N 等于 Y * 2^N(2的N次方)

再比如,我们要求一个整数是奇数,还是偶数,我们可以用按位与,如 N & 1 ,如果得1则表示奇数,0为偶数,当然还有很多,有兴趣的可以深入研究

PS:鉴于可读性考虑,项目中除非必要,还是尽量不使用
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值