逻辑运算与位运算
逻辑运算
在程序设计中的逻辑运算有boolean逻辑运算和位逻辑运算两种,boolean逻辑运算是求判断条件的真假,返回的值是boolean类型;位逻辑运算一般是对整型数据(int)类型的运算,返回的int类型的数据。
boolean逻辑运算
boolean逻辑运算主要有与(&&)运算、或(||)运算和非(!)运算。
a&&b,只有当a和b同时为真时才能为真,其余为假;如
a||b,只有当a和b同时为假时才能为假,其余为真;
!a,若a为真,则!a为假;若a为假,则!a为真;
其中,&与&&有类似的功能,|与||有类似功能,关于它们之间的区别,请看下面的“&&与&及||与|的区别”
位逻辑运算
位逻辑运算主要有与(&)、或(|)、非(~),也叫做求反、 异或(^)。
&,|,~和^主要用于二进制的位运算,它们之间的真值表如下
A | B | A&B | A|B | ~A | A^B |
0 | 0 | 0 | 0 | 1 | 0 |
0 | 1 | 0 | 1 | 1 | 1 |
1 | 0 | 0 | 1 | 0 | 1 |
1 | 1 | 1 | 1 | 0 | 0 |
与运算:真真为真,其余为假;
或运算:假假为假,其余为真;
非运算:你真我假,你假我真;
异或运算:异真同假。
如:
5&3=10000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0001
-5&3=31111 1111 1111 1111 1111 1111 1111 1011(101的补码,负数是以补码的形式进行运算的)0000 0000 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0011
5|3=70000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0111
~5=-60000 0000 0000 0000 0000 0000 0000 0101 1111 1111 1111 1111 1111 1111 1111 1010
~-5=41111 1111 1111 1111 1111 1111 1111 1011 0000 0000 0000 0000 0000 0000 0000 0100
5^3=60000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0000 0011 0000 0000 0000 0000 0000 0000 0000 0110
&&与&及||与|的区别
一度被”&&”与”&”及”||”与”|”搞得头昏脑胀,今天特地去查了一下,在CSDN论坛看到一篇非常不错的帖子:。我对各位大侠的观点进行了深入研究,并对它们分别做了一遍测试,最后整理如下:
&&和&两个运算符都能用在布尔运算中。&&是逻辑“与”运算;&即可以用于逻辑“与”运算也可以位运算。
用于boolean逻辑运算时
计算p1&&p2时,Java先计算p1,若p1为true再计算p2;若p1为false,则不再计算P2,因此,&&又称为条件与运算符。而&的两个运算对象都要计算,所以,&又称为无条件与运算符。 "||"与”|”的情况类似 ,||是条件或运算符,p1 || p2,Java先计算p1,若p1为false再计算P2,若P1为true,则不再计算P2; "|" 无条件运算符,两边对象都要计算。即&&和||即有短路运算的性质,也叫短路运算符,而&和|不具有短路的性质,是非短路运算。
测试
测试1
int a = 3, b = 4;System.out.println((a<0)&&(b--<0));System.out.println("a:" + a + " b:" + b);
结果:
false
a:3 b:4
分析:
因为&&是短路运算,a<0为假,直接得出结果为假,故b--<0不再运算。所以b=4
测试2
int a = 3, b = 4;System.out.println((a<0)&(b--<0));System.out.println("a:" + a + " b:" + b);
结果:
false
a:3 b:3
分析:
因为&是非短路运算,(a<0)和(b--<0)都得运算,所以b=3
同理,对||与|也是如此,如下:
测试3
int a = 3, b = 4;System.out.println((a>0)||(b--<0) );System.out.println("a:" + a + " b:" + b);结果:
true a:3 b:4分析:
因为||是短路运算,a>0为真,直接得出结果为真,故b--<0不再运算。所以b=4
测试4
int a = 3, b = 4;System.out.println((a>0)|(b--<0) );System.out.println("a:" + a + " b:" + b);结果:
true a:3 b:3 分析:
因为&是非短路运算,(a>0)和(b--<0)都得运算,所以b=3
用于位逻辑运算
&和|还可以用于位逻辑运算,
&与|的逻辑位运算已经在上面讲了,如:
6&5=4
6: 0110
5: 0101
0110 & 0101 = 0100
6|5=7
6: 0110
5: 0101
0110 | 0101 = 0111
总结
在进行条件判断时(如如if和while中)用&&和||;
在进行位运算时用&和|;
位移运算
位移运算有“>>右移”;“<< 左移”;“>>> 无符号右移”
n>>k即将整数n的二进制的每一位向右移动k位,左端补充k位符号位,相当将n/(2^k).如:
-5>>3=-11111 1111 1111 1111 1111 1111 1111 1011 1111 1111 1111 1111 1111 1111 1111 1111
其结果与Math.floor((double)-5/(2*2*2))完全相同。
5>>3=00000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0000 0000其结果与 5/(2*2*2)完全相同。
n<<k即将整数n的二进制的每一位向左移动k位,右端补充符k个0,相当将n*2^k.如:
-5<<3=-401111 1111 1111 1111 1111 1111 1111 1011 1111 1111 1111 1111 1111 1111 1101 1000 其结果与 -5*2*2*2完全相同。
5<<3=400000 0000 0000 0000 0000 0000 0000 0101 0000 0000 0000 0000 0000 0000 0010 1000其结果与 5*2*2*2完全相同。
n>>>k即将整数n的二进制的每一位向右移动k位,左端补充k个0,相当将n/(2^k).如:
-5>>>3=536870911 1111 1111 1111 1111 1111 1111 1111 1011 0001 1111 1111 1111 1111 1111 1111 1111
5>>>3=00000 0000 0000 0000 0000 0000 0000 01010000 0000 0000 0000 0000 0000 0000 0000