java位运算

java位运算

位运算表达式由操作数和位运算符组成,实现对整数类型的二进制数进行位运算。位运算符可以分为逻辑运算符(包括~|^)及移位运算符(包括>><<>>>)。

二进制表示

二进制第一位为符号位,0表示正数,1表示负数。

1.正数表示,例如:int类型值 5(int用32位表示)

5 = 0000 0000 0000 0000 0000 0000 0000 0101

2.负数表示,例如:int类型值 -5

-5 = 1111 1111 1111 1111 1111 1111 1111 1011

负数二进制表示方法如下:

首先来个正数5

5 = 0000 0000 0000 0000 0000 0000 0000 0101

这个就是原码,然后原码取反(0的变成1,1的变成0),得到反码

原码: 0000 0000 0000 0000 0000 0000 0000 0101
反码: 1111 1111 1111 1111 1111 1111 1111 1010

反码进行加1得到补码

原码: 0000 0000 0000 0000 0000 0000 0000 0101
反码: 1111 1111 1111 1111 1111 1111 1111 1010
补码: 1111 1111 1111 1111 1111 1111 1111 1011

最终得到的补码就是负数在计算机中的二进制表示方法

3.二进制转换为十进制

正数不讲,略…, 这里只说负数,先随便来一个负数二进制

负数二进制: 1111 1111 1111 1111 1111 1111 1111 1011

负数二进制,减1

负数二进制: 1111 1111 1111 1111 1111 1111 1111 1011
二进制减一: 1111 1111 1111 1111 1111 1111 1111 1010

取反

负数二进制: 1111 1111 1111 1111 1111 1111 1111 1011
二进制减一: 1111 1111 1111 1111 1111 1111 1111 1010
减一后取反: 0000 0000 0000 0000 0000 0000 0000 0101

然后计算得到结果为5,那么负数二进制就为-5

逻辑运算符

1.非(~)运算 : 取反

System.out.println(~5);// 结果为-6 

5  = 0000 0000 0000 0000 0000 0000 0000 0101 = 5
~5 = 1111 1111 1111 1111 1111 1111 1111 1010 = -6

2.与 (&)运算 : 有0出0;全1出1

System.out.println(5 & 3);// 结果为1

5     = 0000 0000 0000 0000 0000 0000 0000 0101 = 5
3     = 0000 0000 0000 0000 0000 0000 0000 0011 = 3
5 & 3 = 0000 0000 0000 0000 0000 0000 0000 0001 = 1

3.或(|)运算 : 有1出1;全0出0

System.out.println(5 | 3);// 结果为7

5     = 0000 0000 0000 0000 0000 0000 0000 0101 = 5
3     = 0000 0000 0000 0000 0000 0000 0000 0011 = 3
5 | 3 = 0000 0000 0000 0000 0000 0000 0000 0111 = 7

4.异或(^)运算: 相同得0;相异得1

System.out.println(5 ^ 3);//结果为6 

5     = 0000 0000 0000 0000 0000 0000 0000 0101 = 5
3     = 0000 0000 0000 0000 0000 0000 0000 0011 = 3
5 ^ 3 = 0000 0000 0000 0000 0000 0000 0000 0110 = 6

A.小应用

一个数字标识位表示多种逻辑,例如:一个任务可分成n个独立小任务,每个小任务之间不分先后顺序,当所有小任务完成则表示此任务完成。

如果n=3,则将3个小任务分别用$2^0$,$2^1$,$2^2$即1,2,4表示

//更新当前任务完成第1个小任务
update tbl_task set status = status|1 where id=1;
//同理,更新当前任务完成第2个小任务
update tbl_task set status = status|2 where id=1;
//同理,更新当前任务完成第3个小任务
update tbl_task set status = status|4 where id=1;
//当status = 7时,则表示三个任务都完成;

//查询第1个小任务未完成的所有任务
select * from tbl_task where status&1=0;
//查询第1个小任务已完成的所有任务
select * from tbl_task where status&1=1;

//同理,第2个小任务
//查询第2个小任务未完成的所有任务
select * from tbl_task where status&2=0;
//查询第2个小任务已完成的所有任务
select * from tbl_task where status&2=2;

移位运算符

1.左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数(在低位补0)。

System.out.println(5 << 3);// 运行结果是40

5      = 0000 0000 0000 0000 0000 0000 0000 0101 = 5
5 << 3 = 0000 0000 0000 0000 0000 0000 0010 1000 = 40

2.“有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定的位数。 “有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。

System.out.println(5 >> 3);// 运行结果是0

5      = 0000 0000 0000 0000 0000 0000 0000 0101 = 5
5 >> 3 = 0000 0000 0000 0000 0000 0000 0000 0000 = 0

System.out.println(-5 >> 3);// 结果是-1

-5      = 1111 1111 1111 1111 1111 1111 1111 1011 = -5
-5 >> 3 = 1111 1111 1111 1111 1111 1111 1111 1111 = -1

3.Java也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0。这一运算符是C或C++没有的。

System.out.println(5 >>> 3);// 结果是0

5       = 0000 0000 0000 0000 0000 0000 0000 0101 = 5
5 >>> 3 = 0000 0000 0000 0000 0000 0000 0000 0000 = 0

System.out.println(-5 >>> 3);// 结果是536870911

-5       = 1111 1111 1111 1111 1111 1111 1111 1011 = -5
-5 >>> 3 = 0001 1111 1111 1111 1111 1111 1111 1111 = 536870911

打赏一个呗

取消

感谢您的支持!!!

扫码支持
扫码支持
扫码打赏

打开支付宝或微信扫一扫,即可进行扫码打赏哦