逻辑与(and)运算:两个变量都为真,结果才为true
逻辑或(or)运算:两个变量有一个为真,则结果才为true
逻辑非(取反)运算:如果结果是真,则变为假,如果结果是假,则变为真
短路运算:从下面实验可以得出,与(and)运算一旦确认第一个条件为假,则不会在执行第二个条件。
//逻辑运算符 public class Demo05 { public static void main(String[] args) { // 与(and) 或(or) 非(取反) boolean a = true; boolean b = false; System.out.println("a && b:"+(a&&b));//逻辑与运算:两个变量都为真,结果才为true System.out.println("a || b:"+(a||b));//逻辑或运算:两个变量有一个为真,则结果才为true System.out.println("! (a && b):"+!(a&&b));//如果是真,则变为假,如果是假,则变为真 //短路运算 int c = 5; boolean d = (c<4)&&(c++<4); System.out.println(d);//false 从这两组实验可以得出,与运算一旦确认第一个条件为假,则不会在执行第二个条件。 System.out.println(c);//5 所以c的值为5 boolean e = (c>4)&&(c++<4); System.out.println(d);//false 这里与运算确认第一个条件为真,则会继续执行第二条命令.使c自增 System.out.println(c);//6 } }
重点:在java的位运算中,输入运算位数实际是先与计算机默认运算位数32进行模运算,求得余数才是计算机执行移动位数。
& , |, ^用法:
A = 0011 1100 在二进制里,1为真,0为假。
B = 0000 1101
与(and):A&B = 0000 1100 A与B相同位都为1,则输出1,否则为0.
或 (or):A|B = 0011 1101 A与B相同位之间其中一个为1,则输出1,否则为0.
异或 :A^B = 0011 0001 如果A与B相同位之间不相等,则返回1。相等,返回0.
取反:~B = 1111 0010 如果B位数为0,则返回1。位数为1,则返回0.
这里的二进制编码长度要记得看定义的是什么类型:short 2字节 16位 int 4字节 32 位
正数二进制编码开头为0,负数二进制开头编码为1.
左右移不同之处:右移对正负数的处理方式不一样,而左移不会考虑正负
<<:左移运算符,num << n,相当于num乘以n
这里左移两位溢出舍去,符号位变为1,为负数
运算规则:高位溢出舍去,低位补0.
>> :右移运算符,num >> n,相当于num除以n
这里的补位规则保证正数运算完还是正数,负数运算完还是负数.
正数右移:低位溢出舍去,高位补0
负数右移:低位溢出舍去,高位补1
>>> : 无符号右移运算
丢弃低位,高位补0: 则所有非0数字经过无符号右移都将变为正数
如果无符号右移超过32位会怎么样呢?
>>> 表示无符号右移n位,无论正负数,前面都补0。 以-2>>>32为例,按Java位运算符定义,-2的二进制无符号右移32位,-2的二进制10000000 00000000 00000000 00000010,在计算机中的补码为11111111 11111111 11111111 11111110,无符号向右移32为后的二进制补码为00000000 00000000 0000000 00000000,对应的十进制为0,即-2>>>32 = 0 。 但是,实际编译后的十进制结果为-2,二进制补码为11111111 11111111 11111111 11111110。源码和输出结果如下: 源码: int x = -2; x=x>>>32; System.out.printin(x);//-2 输出结果: 分析原因:在java虚拟机中,执行-2>>>(32)时,实际是执行-2>>>(32%32),因为计算机默认32位运算,“()”内的位移数据实际与默认32位进行模运算,余数为几就右移几位。所以本例子中实际是右移0位,所以-2>>>(32)结果仍为-2 。同理:“>>” “<<” “>>>” 也遵循这个原理。 结论:在java的位运算中,输入运算位数实际是先与计算机默认运算位数32进行模运算,求得余数才是计算机执行移动位数。
public class Demo06 { public static void main(String[] args) { /* A = 0011 1100 在二进制里,1为真,0为假。 B = 0000 1101 ----------------------------------------------- 与:A&B = 0000 1100 A与B为1,则输出1,否则为0. 或:A|B = 0011 1101 A与B其中一个为1,则输出1,否则为0. 异或:A^B = 0011 0001 如果A与B不相等,则返回1。相等,返回0. 取反:~B = 1111 0010 如果B一位为0,则返回1。一位为1,则返回0. 面试题:2*8 = 16怎么算比较快? 2*2*2*2 位运算效率极高!!! >> 右移:在二进制里所有的1向右移动 << 左移:在二进制里所有的1向左移动 0000 0000 0 0000 0001 1 0000 0010 2 0000 0011 3 0000 0100 4 0000 1000 8 0000 1100 12 0001 0000 16 */ System.out.println(2<<3);//16 即0000 0010 变成了 0001 0000 System.out.println(3<<2);//12 即0000 0011 变成了 0000 1100 } }
面试题:2*8 = 16怎么算比较快? 2*2*2*2 位运算效率极高!!! >> 右移:在二进制里所有的1向右移动 << 左移:在二进制里所有的1向左移动 0000 0000 0 0000 0001 1 0000 0010 2 0000 0011 3 0000 0100 4 0000 1000 8 0000 1100 12 0001 0000 16 */ System.out.println(2<<3);//16 即0000 0010 变成了 0001 0000 System.out.println(3<<2);//12 即0000 0011 变成了 0000 1100 这就是左移,右移