1.位运算

一.位运算的奇淫技巧

1.判断奇偶性

代码演示

使用位运算,判断奇偶性

System.out.println(31&1);
System.out.println(30&1);

输出:

1  //31是奇数
0  //30是偶数

解释

与(AND)运算:当A和B全为1时,输出1,否则输出0。
&01
000
101
(31)   →   (0000 0000 ....... 0001 1111)
(1)    →   (0000 0000 .............0001)    &
 =         (0000 0000 .............0001)    →    (1)  奇数
-----------------------------------------------------------
(30)   →   (0000 0000 ....... 0001 1110)
(1)    →   (0000 0000 .............0001)    &
 =         (0000 0000 .............0000)    →    (0)  偶数

2.交换两个整数变量的值

代码演示

利用位运算,直接交换两个整数变量的值

int a = 10;
int b = 8;
a = a^b;
b = a^b;
a = a^b;
System.out.println("a = "+a);
System.out.println("b = "+b);

输出:

a = 8
b = 10

解释

异或(xor)运算:两个数不相同为1,相同为0;不进位的加法,1+1=0,0+0=0,1+0=0。
^01
001
110
异或运算的性质
1.任何数和自己异或皆为0。
2.任何数与另一个数连续异或两次还是自己。
第一次运算:
	a =  (10)  =  0000.............1010
	b =   (8)  =  0000.............1000  ^
	              0000.............0010     
	将结果赋值给a后
			  a = 0000.............0010
			  b = 0000.............1000
--------------------------------------------------
第二次运算:
	          a = 0000.............0010
	          b = 0000.............1000   ^
	              0000.............1010
	 将结果赋值给b后
	 		  a = 0000.............0010
	 		  b = 0000.............1010(此时b已经得到a的值)
--------------------------------------------------	 			
第三次运算:          
	  		  a = 0000.............0010
	 		  b = 0000.............1010  ^
	 		  	  0000.............1000
	 将结果赋值给a后
			  a = 0000.............1000
			  b = 0000.............0010
	 交换完成
--------------------------------------------------	
a = a^b;
b = a^b; 相当于初始的a连续异或b两次:a^b^b 此时得到值为a,又将他赋值给b
a = a^b; 此时b的值已经是初始a的值,a的值是初始a异或初始b的值,此时的a^b等价于初始的b连续异或两次a,结果是初始b的值,把他赋值给a,交换完成。

3.求函数绝对值

代码演示

System.out.println(8+ "的绝对值是:"+((8^(8>>31))+(8>>>31)));
System.out.println(-8+ "的绝对值是:" + ((-8^(-8>>31))+(-8>>>31)));

输出:

8的绝对值是:8
-8的绝对值是:8

补充

1.左移: <<

左移,即除符号位外,所有二进制位向高位移动指定位数,低位补0。左移一位,等价于一个数扩大2倍。
代码演示:

System.out.println(10<<2);  //<<符号左边是要作出移动的数,右边是要移动几位

输出:

40

解释:

 (10) = 0000........0000 1010
 <<2  = 0000........0010 1000  = (40)
2.右移: >>

右移,即除符号位外,所有二进制位向低位移动指定位数,高位补符号位。右移一位,约等于一个数缩小2倍(会产生精度丢失)。
代码演示:

System.out.println(10>>2);
System.out.println(-10>>2);

输出:

2
-3

解释:

 (10) = 0000........0000 1010
 >>2  = 0000........0000 0010  = (2)
 --------------------------------------------------	
 (-10) = 1111........1111 0110(补)    负数的补码
 >>2  = 1111........1111 1101(补)  =  1000.........0011(原) = -3
2.无符号右移: >>>

无符号右移,即向右移位时,连同符号位一起移动,最高位补0
代码演示:

System.out.println(-10>>>2);

输出:

1073741821

解释:

 (-10) = 1111........1111 0110(补)
>>>2   = 0011........1111 1101(补)  = 1073741821(补码直接转换为真值)

解释

整数在java中占4个字节,32位,
8>>>31和-8>>>31为了得到数字的最高位


8>>31 得到一串32位全为0的二进制数,此数与8异或,还是8,加上先前的8>>>31得到8
-8>>>31得到一串32位全为1的二进制数,此数与-8异或,相当于对-8连同符号位一起取反,然后加上-8>>>31。负数的补码等于正数连同符号位取反加一,负数求绝对值相当于此过程的逆过程。

才疏学浅,如果有写的不对的地方,请在评论区给出,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值