搞懂java中的位运算

这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战

什么是位运算?

程序中的所有数值在计算机中都是以二进制的形式存储的,位运算就是对这些二进制形式存储的数据进行一元和二元操作,通俗点说就是对我们存储的数值的二进制进行操作。 没有了转换这一步而是直接对二进制进行操作,理论上位运算比加减运算略快,比乘除法要快很多,但是在现在 java程序架构 上位运算和加减法效率相同,比乘除法要快,当然如果是进行大量的计算使用位运算能有效的提升性能

JAVA中有哪些位运算符?

主要有以下几种位运算:&|^~>><<>>>

&| 虽然作为逻辑运算符使用在数值上时也可以做为位运算使用

位运算符的使用

&

当两个对应数的位数同为1时,结果为1,否则为0

简单点讲就是把十进制的数值转换成二进制,然后对应位数进行对比如果同为1那么最后的数字为1,否则该位数就位0

举例

	十进制
	5 & 7
	二进制
	101 & 111
	结果:
	十进制:5
	二进制:101
复制代码

过程:运算的时候二进制对应位数进行比对 101111,两个数值对比只有中间位数没有同时为1,那么最后的运算结果就为 101

扩展:判断数值的奇偶性,数值 & 1,由于1的二进制是001,那么不管数值是多少只会对比最后一位数是否为1,如果同为1则证明该数值为奇数,如果结果为0则证明该数为偶数

|

&运算刚好相反当两个对应数的位数同为0时,结果为0,否则为1

简单点讲就是把十进制的数值转换成二进制,然后对应位数进行对比如果同为0那么最后的数字为0,否则该位数就位1

举例

	十进制
	4 | 8
	二进制
	0100 & 1000
	结果:
	十进制:12
	二进制:1100
复制代码

过程:运算的时候二进制对应位数进行比对 01001000,两个数值对比只有前面两位没有同时为0 则前面两位为1后两位为0,转为十进制为12

扩展:把数值转换为最接近的的奇数等于当前数为偶数时 +1,用法就是 数值 | 1

^

对应位数相同则为 0 ,相同则为 1

简单点讲就是把十进制的数值转换成二进制,对应位数进行比较如果相同则对应位数结果为0,否则为1

举例

	十进制
	5 | 8
	二进制
	0101 & 1000
	结果:
	十进制:13
	二进制:1101
复制代码

过程:运算的时候二进制对应位数进行比对 01011000,两个数值对比如果对应位数相同结果为0,否则为1,只有第二位相同其它不同所以输出结果为 1101

扩展:可以作为简单加密方式,比如我现在银行的支付密码为123456,然后把我开户年月作为密匙202111,123456 ^ 202111 = 194367,然后把194367进行持久化,最后得到支付密码的时候只需要反向再计算一次

~

这个会让二进制数值进行反运算,比如会 0变为11变为0

举例

	二进制:101 就会变成 11111…..1010 
复制代码

过程:虽然二进制101前面没有值,但是对于二进制前面的值都是为0,所以进行反运算之后就会用1填满

<<

左位移运算,向左边进行位运算

简单点讲就是把十进制的数值转换成二进制,然后最高位向左移动,或者理解为2乘以数值次数

举例

	十进制
	10<<2
	二进制
	1010 << 2
	结果:
	十进制:40
	二进制:101000
复制代码

过程:十的二级制为1010 将该值往左边移动两位并补齐0最终值为101000,可以理解为1022

>>

右位移运算,向右边进行位运算,如果最后一位为1也会舍去

简单点讲就是把十进制的数值转换成二进制,然后从最高位开始向右移动,或者理解为2除以数值次数并向下取整,如 5 / 2 等于 2.5但是向下取整最后的结果会舍掉 0.5 所以结果为2

举例

	十进制
	5>>1
	二进制
	101 >> 1
	结果:
	十进制:2
	二进制:10
复制代码

过程:5转换为二进制为 101,然后向右边移动一位数最后的1会被舍去掉结果则为10

小结

在java中不止前面这几种位运算还有java特有>>> 不带符号的位运算,带符号的位运算 符**>>** 总是自动的用它之前的最高位数值内容去补它的最高位这样就保留了之前值的符号,而不带符号的 >>> 不会在最高位保留之前的值而是在高位补0 不止有不带符号的 >>> 运算,还有 >>>=

おすすめ

転載: juejin.im/post/7032307726063501349