hi~本期学习位运算,学完了就开始学习算法了。为啥要学习位运算呢,就从基本java的来说,我们再去看jdk源码的时候,发现很多地方都用到位运算尤其数据结构方面。位运算主要是直接操控二进制时使用 ,主要目的是节约内存,使你的程序速度更快。
位运算主要包括按位与(&)、按位或(|)、按位异或(^)、取反( ~ )、左移(<<)、右移(>>)这几种。其中除了取反( ~ )以外,其他的都是二目运算符,即要求运算符左右两侧均有一个运算量。
1、按位与(&)
运算的两个数,转换算为二进制后,进行与(&)运算。当对应位上的数都是1时,该位取1,否则该为0。
运算规则:0&0=0 0&1=0 1&0=0 1&1=1
例: 5 & -5
5 : 0000 0000 0101
-5 :1111 1111 1011
答案 : 0000 0000 0001
应用:
- 判断奇偶
int a;
if(a&1 == 0) 则 a 为偶数
if(a&1 == 1) 则 a 为奇数
很好理解:将a转化为二进制,a&1==0 为true的话,说明a的第一位为0,那就说明是2的倍数,那就是偶数,反之亦然。
- 取一个整数二进制数中某些位
int a = 46;
int i1 = a & 0b00001111;//即取a的后4位,0b开头表示二进制数
System.out.println(i1);
String s = Integer.toBinaryString(i1);
System.out.println(s);
这个也很好理解,与你相同,必为1,1&1得1,反之必为0,0&1得0 所以可以找到一个数的二进制的后四位。
- 判断整数是否是2的幂次方
private static boolean isPower(int n) {
if (n <= 0) {
return false;
}
return (n & (n - 1)) == 0;
}
2的整次幂在二进制表示有一个特点,最高位为1其他低位全部为0,减一后,反过来,高位0,后面低位皆为1.然后在&运算。从低位到高位全部为0。
2、按位或(|)
运算的两个数,转换为二进制后,进行或(|)运算。只要相应位上存在1,那么该位就取1,如果都不为1,就为0。
运算规则:0|0=0 0|1=1 1|0=1 1|1=1
例:还是5 | -5
0000 0000 0101
1111 1111 1011
可以看到每一位中其中一个都有1
答案 :111111111111
注意:负数按补码形式参加按位或运算。
- 将一个数变成其最接近的偶数
int a = 15;
int i = (a | 1) - 1;// 位运算优先级低于四则运算故加( )
System.out.println(i);
当a是奇数的时候,(a | 1) - 1就等于a-1 奇数减一等于偶数;
当a是偶数的时候,(a |1)-1就等于 a,已经是偶数不变;
3、按位异或(^)
运算的两个数,转换成二进制数后,进行异或(^)运算,如果相应位置上的数相同,该位取0,如果不同该位取1。
运算规则:0^0=0 0^1=1 1^0=1 1^1=0
- 交换律
- 结合律 (a^b)^c == a^(b^c)
- 对于任何数x,都有 x^x=0,x^0=x
- 自反性: a^b^b=a^0=a;
- a ^ b = c, 则 c ^ b = a
4、取反(~)
是按位取反运算,如果a是有符号整型,则 ~a = -(a+1)
例:
5 : 0000 0000 0101
~5 : 1111 1111 1010
5、左移(<<)
将一个数二进制下的数向左移若干位,比如 x << y 就是将二进制下的x 向左移 y 位
例 : 5 << 5
5 : 0000 0000 0101
5 << 5 : 0000 1010 0000
在10进制下就等于160
我们可以思考一下,在十进制中,一个数每乘一次10就向左进一位。那么在二进制中,同10进制一样,二进制中每乘一次2就向左进一位,那么一个数左移x 就等价于一个数乘 2x。即a*;
6、右移(>>)
右移运算,表示对整数对应的二进制数右移,右移一位,即表示除以2,a >> n 即 a/,与左移相反。
好了,数据结构的部分目前在我的计划的部分已经完结了,当然后面会不断学习,然后在这个基础上去拓展。
下期就真的开始算法啦~,下期学习常见的排序算法或算法思想简介,二选一,这个我要思考下,如何踏出第一步。
PS:我开通了微信公众号,里面有关于数据结构全部资料,每天多学一点点比什么都实在。