1.异或: 在java中 ,运算 符号是 ^ , 只有 n ^ 0时才能得 n 相等两个数 异或 得 0,
1 ^ 0 = 1; 1^1=0;
n ^ n = 0; n ^ 0=n; a ^ b ^ c = a ^ (b ^ c);
有了以上的基础,异或运算符可用于翻转 二进制数, 比如 :
一: 翻转低四位
x = 1110 1010
x ^ 0000 1111 = 1110 0101
2. 与 操作: & 只有同时为 1 时,才得1 1 &1=1; 1&0=0; 0&0=0;
例子:
一: 置指定位数为0(取高四位):
x = 1001 1011 置 低四位为0
x & 1111 0000= 1001 0000
二:清零 n & 0 =0
三:hashMap源码
static int indexFor(int h, int length) {
// assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
return h & (length-1);
}
h是 当前key的哈希码, 哈希码 是通过 HashMap中的hash方法获取到 的。
h & (length -1) ; length 是 hashMap的长度
这里 相当于h % 2的N次方 hashMap长度肯定是2的N次方 可以试试哦~
所以公式: n & (2的n次方-1) = n%2的n次方
四:实战 输入一个数,求这个数二进制 含有多少个1 note:这个数可能为负数
第一种解法:逐位判断 n,判断一次,把n向右移动一位,等于 用1 判断下一位, 只有当这一位是1时,结果才为1,不为0,循环n的长度
int count = 0;
while( n != 0){
if(n & 1 != 0){
count++;
}
n >>> 1;
}
第二种解法:移位1,循环n的长度
int count = 0,flag = 0;
while(flag < n){
if(n & flag != 0){
count ++;
}
flag << 1;
}
第三种解法:每次消去 n里面的一个1 通过n & (n-1) 每次可以消去1个1,n-1肯定会改变某一位的1为0 然后在与之前的n相&,就消去了这个1,其他位的1不变。这个循环n的1 的个数次
int count = 0;
while(n!=0){
count ++;
n = n & (n-1);
}
第三种为最优解。
第一种解法要注意,要用无符号右移,如果为负数时,>> 会让第一位一直是1,无限循环下去。
3. 或操作:java中的符号 |:
0 | 0 = 0; 1 | 0 = 1; 1 | 1 = 1;
应用:将 x = 1010 0000 低四位置1
x | 0000 1111 = 1010 1111
4. 取反 ~ ~1=0 ~0=1
附加: 计算机中负数 的二进制,是用正数的补码表示。
比如 5:
0000 0000 0000 0000 0000 0000 0000 0101.
反码:
1111 1111 1111 1111 1111 1111 1111 1010
补码:
-5:1111 1111 1111 1111 1111 1111 1111 1011