与运算
与运算 & 规则 :都为1时才为1
System.out.println( 7 & 9);
/*
* 7二进制 0111
* 9二进制 1001
* -----------
* 0001 ==1
* */
案例:取模
h & (length-1),前提是length必须是2的n次方,HashMap的扩容机制就用到了这种方法
System.out.println(10 & (4 - 1)); // 2
或运算
或运算 | 规则:有一个为1,则为1 |
System.out.println(7 | 9);
/*
* 7二进制 0111
* 9二进制 1001
* ----------
* 1111 == 15
* */
异或运算
异或运算 ^ 规则:不同为1
System.out.println( 7 ^ 9);
/*
* 7二进制 0111
* 9二进制 1001
* ----------
* 1110 == 14
*
* */
取反运算
//取反运算(计算机存储的是补码,取反其实是针对补码进行取反)
//http://blog.csdn.net/poxu1234/article/details/62422231
//1.计算机中存储整数都是用的补码,取反运算也是对补码进行取反
//2.所有的数字大小都是根据原码的大小计算的
//3.正整数的反码,补码和原码相同。负整数的反码是除了符号位以外取反,补码为反码+1
//4.对补码再求补码即是原码
//取反运算 ~ 规则:按位取反
System.out.println( ~7);
/*
* 7二进制 0000 0000 0000 0000 0000 0000 0000 0111
* 7的补码是本身 0000 0000 0000 0000 0000 0000 0000 0111 正数的补码和反码都是本身
* 取反操作 1111 1111 1111 1111 1111 1111 1111 1000 取反之后变成负数了,负数的补码=符号位不动,其他位取反+1,也就是反码+1
* 补码的补码 1000 0000 0000 0000 0000 0000 0000 1000 得到-8
*
* */
System.out.println(~-7);
/*
* -7二进制 1000 0000 0000 0000 0000 0000 0000 0111
* -7的补码 1111 1111 1111 1111 1111 1111 1111 1001 负数的反码=符号位不动,其他位取反;负数的补码=符号位不动,其他位取反+1,也就是反码+1
* 取反操作 0000 0000 0000 0000 0000 0000 0000 0110
* 补码的补码 0000 0000 0000 0000 0000 0000 0000 0110 得到6
*
* */
位移
>>
右位移,相当于除以2
>>>
无符号右位移,对于正数相当于除以2,对于负数,高位补0
int a = 8 >> 1;
System.out.println(a);// 4
int b = -8 >> 1;
System.out.println(b);// -4
int c = 8 >>> 1;
System.out.println(c);// 4
int d = -8 >>> 1;
System.out.println(d);// 2147483644
System.out.println(Integer.toBinaryString(-8));// 11111111111111111111111111111000
案例
使用同一个int或long字段存储多种状态值
/**
* 通过位移操作将多个bit状态值存储到同一个字段中,注意状态值只能有(是 or 否),64位机器最多可以同时管理63种状态(long类型,首位是符号位)
*
* 示例:用一个状态值来存储小明是否交了各门作业
**/
public class BitStatusUtils {
// A:语文 B:数学 C:英语 D:物理 E:化学 F:生物 G:历史 H:地理
// 二进制表示 0001 没有交任何作业
public static final long NONE = 1 << 0;
// 语文 0000 0000 0010
public static final long CHINESE = NONE << 1;
// 数学 0000 0000 0100
public static final long MATH = NONE << 2;
// 英语 0000 0000 1000
public static final long ENGLISH = NONE << 3;
// 物理 0000 0001 0000
public static final long PHYSICS = NONE << 4;
// 化学 0000 0010 0000
public static final long CHEMISTRY = NONE << 5;
// 生物 0000 0100 0000
public static final long BIOLOGY = NONE << 6;
// 历史 0000 1000 0000
public static final long HISTORY = NONE << 7;
// 地理 0001 0000 0000
public static final long GEOGRAPHY = NONE << 8;
// 所有作业都交了 0001 1111 1111
public static final long ALL =
NONE | CHINESE | MATH | ENGLISH | PHYSICS | CHEMISTRY | BIOLOGY | HISTORY | GEOGRAPHY;
/**
* @param status
* 所有状态值
* @param value
* 需要判断状态值
* @return 是否存在
*/
public static boolean hasStatus(long status, long value) {
return (status & value) != 0;
}
/**
* @param status
* 已有状态值
* @param value
* 需要添加状态值
* @return 新的状态值
*/
public static long addStatus(long status, long value) {
if (hasStatus(status, value)) {
return status;
}
return (status | value);
}
/**
* @param status
* 已有状态值
* @param value
* 需要删除状态值
* @return 新的状态值
*/
public static long removeStatus(long status, long value) {
if (!hasStatus(status, value)) {
return status;
}
return status ^ value;
}
/**
* 是否交了含有全部状态
*
* @param status
* @return
*/
public static boolean hasAllStatus(long status) {
return (status & ALL) == ALL;
}
public static void main(String[] args) {
// NONE | CHINESE | MATH | ENGLISH | PHYSICS | CHEMISTRY | BIOLOGY | HISTORY | GEOGRAPHY;
System.out.println(Long.toBinaryString(NONE));
System.out.println(Long.toBinaryString(CHINESE));
System.out.println(Long.toBinaryString(MATH));
System.out.println(Long.toBinaryString(ENGLISH));
System.out.println(Long.toBinaryString(PHYSICS));
System.out.println(Long.toBinaryString(CHEMISTRY));
System.out.println(Long.toBinaryString(BIOLOGY));
System.out.println(Long.toBinaryString(HISTORY));
System.out.println(Long.toBinaryString(GEOGRAPHY));
System.out.println(Long.toBinaryString(ALL));
// int类型可以存储31种状态,1111111111111111111111111111111
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE));
// long类型可以存储63种状态,111111111111111111111111111111111111111111111111111111111111111
System.out.println(Long.toBinaryString(Long.MAX_VALUE));
long status = addStatus(NONE, CHINESE);
System.out.println("小明交了语文作业:" + status);
status = addStatus(status, PHYSICS);
System.out.println("小明又交了物理作业:" + status);
status = addStatus(status, HISTORY);
System.out.println("小明还交了历史作业:" + status);
status = removeStatus(status, HISTORY);
System.out.println("小明撤销了历史作业:" + status);
System.out.println("小明是否交了语文作业:" + hasStatus(status, CHINESE));
System.out.println("小明是否交了历史作业:" + hasStatus(status, HISTORY));
System.out.println("小明是否交了生物作业:" + hasStatus(status, BIOLOGY));
System.out.println("小明是否交了全部作业:" + hasAllStatus(status));
}
}