1.位操作符
按位操作符和逻辑操作符使用的是相同的符号,所以理解起来也还好。
按位操作符操作的是比特(bit),就是二进制位这些东西(“1001010100”)
简单说一下进制转换 二进制转十进制 :
1字节 byte 占8位(bit) : 0000 1011 = 1*1 + 1*2 +0*4 + 1* 8 = 11;
一个字节最大值 0111 1111 = 127 0位表示该字节是正数
注意: 数字在计算机中是以二进制补码形式保存的,正数的原码、补码都是一样的,而负数的补码是其绝对值反码加1。因此,正整数的二进制转换比较容易,负整数就醉了。
二元操作符:
“&” 在位运算的时候就是并且的意思 ,下面根据 & 操作符规则进行 二进制的相加
public static void main(String[] args) { // 十进制 二进制 int a = 10; // 0000 0000 0000 0000 0000 0000 0000 1010 int b = 6; // 0000 0000 0000 0000 0000 0000 0000 0110 int c = a & b; // 0000 0000 0000 0000 0000 0000 0000 0010 System.err.println(c); // 输出 :2 }
“|” 在位运算的时候是或者的意思,下面根据 | 操作符规则进行 二进制的相加
public static void main(String[] args){ // 十进制 二进制 int a = 10; // 0000 0000 0000 0000 0000 0000 0000 1010 int b = 6; // 0000 0000 0000 0000 0000 0000 0000 0110 // 因为|是二元运算符 所以可以这样写 参照(a+=b)理解 a |= b; // 0000 0000 0000 0000 0000 0000 0000 1110 System.err.println(a); // 输出:14 }
“ ^" 在位运算的时候是异或者的意思。不理解-6的二进制?结合下面 ”~“ 案例研究下吧
public static void main(String[] args) { // 十进制 二进制 int a = 10; // 0000 0000 0000 0000 0000 0000 0000 1010 int b = 6; // 0000 0000 0000 0000 0000 0000 0000 0110 int c = a ^ b; // 0000 0000 0000 0000 0000 0000 0000 1100 System.err.println(c); // 输出:12 int aa = 10; // 0000 0000 0000 0000 0000 0000 0000 1010 int bb = -6; // 1111 1111 1111 1111 1111 1111 1111 1010 int cc = aa ^ bb; // 1111 1111 1111 1111 1111 1111 1111 0000 System.err.println(cc); // 输出:-16 }
一元操作符:
"~" (非) 顾名思义就是取反的意思了
public static void main(String[] args) { /** * 推一下-10 的补码 * 0000 0000 0000 0000 0000 0000 0000 1010 10的补码 * 1111 1111 1111 1111 1111 1111 1111 0101 反码 * 1111 1111 1111 1111 1111 1111 1111 0110 反码+1 = -10补码 */ // 十进制 二进制 int c = -10;// 1111 1111 1111 1111 1111 1111 1111 0110 补码 int d = ~c; // 0000 0000 0000 0000 0000 0000 0000 1001 求反的结果 System.err.println(d); // 输出:9 int a = 10; // 0000 0000 0000 0000 0000 0000 0000 1010 补码 int b = ~a; // 1111 1111 1111 1111 1111 1111 1111 0101 求反的结果 System.err.println(b); // 输出:-11 /** * 根据b的补码 反推 b所代表的10进制数 * 1111 1111 1111 1111 1111 1111 1111 0100 补码-1 * 0000 0000 0000 0000 0000 0000 0000 1011 求反 十进制11 因为b的补码首位是1 代表负数 */ }
2.移位操作符
移位是运算的对象是二进制的“位”
1.左移操作符(<<) 按照右侧指定的位数,将左边操作二进制数向左移动 (正负都是)低位补0 ;
public static void main(String[] args) { int i = 3; // 0000 0000 0000 0000 0000 0000 0000 0011 i <<= 2; // 0000 0000 0000 0000 0000 0000 0000 1100 左移两位 补零 System.err.println(i); // 输出:12 int a = -3; // 1111 1111 1111 1111 1111 1111 1111 1101 a <<= 2; // 1111 1111 1111 1111 1111 1111 1111 0100 补码-1 求反 System.err.println(a); // 输出:-12 }
如果对 char 、byte、short 类 型进行移位,移位前会转为 int 类型 结果也是 int 型。
int 类型移位超过32 位 按移位数%32 取余移位
long 类型 结果还是 long
long 类型移位超过64 位 按移位数%64 取余移位
移位只有: long、int
public static void main(String[] args) { int a = 2; byte b = 2; char c = 2; short d = 2; double e = 2; long f = 2; System.err.println(a << 3); // 输出16 System.err.println(a << 35); // 输出16 System.err.println(b << 35); // 输出16 System.err.println(c << 35); // 输出16 System.err.println(d << 35); // 输出16 // System.err.println(e << 35); 无法编译 System.err.println(f << 35); // 输出168719476736 System.err.println(f << 3); // 输出16 System.err.println(f << 67); // 输出16 }
2.右移操作符(>>) 按照右侧指定的位数,将左边操作二进制数向右移动 高位正补0 负补1 ;
public static void main(String[] args) { int i = 11; // 0000 0000 0000 0000 0000 0000 0000 1011 i>>=2; // 0000 0000 0000 0000 0000 0000 0000 0010 右移两位 补零 System.err.println(i); // 输出:2 int a = -11; // 1111 1111 1111 1111 1111 1111 1111 0101 a>>=2; // 1111 1111 1111 1111 1111 1111 1111 1101 补码-1 求反 System.err.println(a); // 输出:-3 }
3. 无符号右移操作符(>>>) 按照右侧指定的位数,将左边操作二进制数向右移动 无论正负都在高位补0 ;
实际对正数没什么影响 负数就又醉了。。
public static void main(String[] args) { int i = 11; // 0000 0000 0000 0000 0000 0000 0000 1011 i>>>=2; // 0000 0000 0000 0000 0000 0000 0000 0010 右移两位 补零 System.err.println(i); // 输出:2 int a = -11; // 1111 1111 1111 1111 1111 1111 1111 0101 a>>>=2; // 0011 1111 1111 1111 1111 1111 1111 1101 右移两位 补零 System.err.println(a); // 输出:1073741821 System.err.println(Integer.toBinaryString(a)); //输出:11 1111 1111 1111 1111 1111 1111 1101 int b = -11; // 1111 1111 1111 1111 1111 1111 1111 0101 b>>>=30; // 0000 0000 0000 0000 0000 0000 0000 0011 右移30位 补零 System.err.println(b); // 输出:3 }