yeskery

JAVA中常用的二进制位操作

二进制介绍

二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”,由18世纪德国数理哲学大师莱布尼兹发现。当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的。计算机中的二进制则是一个非常微小的开关,用“开”来表示1,“关”来表示0。

20世纪被称作第三次科技革命的重要标志之一的计算机的发明与应用,因为数字计算机只能识别和处理由'0'.'1'符号串组成的代码。其运算模式正是二进制。19世纪爱尔兰逻辑学家乔治布尔对逻辑命题的思考过程转化为对符号"0"."1"的某种代数演算,二进制是逢2进位的进位制。0、1是基本算符。因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。

位操作的基本方法

在计算机中所有数据都是以二进制的形式储存的。

位运算其实就是直接对在内存中的二进制数据进行操作,因此处理数据的速度非常快。

方便演示,首先写个二进制打印方法:

  1. private static void printNum(int n){
  2. String num = Integer.toBinaryString(n);
  3. if(num.length() == 32){
  4. System.out.println(num);
  5. }else{
  6. StringBuilder sb = new StringBuilder("");
  7. for(int i =0;i < 32 - num.length(); i ++){
  8. sb.append("0");
  9. }
  10. System.out.println(sb.toString() + num);
  11. }
  12. }

取反

~ 操作符(取反),对应二进制位取反,0变成1,1变成0

  1. int num = 3;
  2. printNum(num);
  3. printNum(~num);

结果如下:

  1. 00000000000000000000000000000011
  2. 11111111111111111111111111111100

与运算

& 操作符(与),对应二进制位进行与操作,都为1时变成1,其他变为0

  1. int num1 = 3;
  2. int num2 = 7;
  3. printNum(num1);
  4. printNum(num2);
  5. printNum(num1 & num2);

结果如下:

  1. 00000000000000000000000000000011
  2. 00000000000000000000000000000111
  3. 00000000000000000000000000000011

或运算

| 操作符(或)对应二进制位进行或操作,都为0时变成0,其他变为1

  1. int num1 = 4;
  2. int num2 = 7;
  3. printNum(num1);
  4. printNum(num2);
  5. printNum(num1 | num2);

结果如下:

  1. 00000000000000000000000000000100
  2. 00000000000000000000000000000111
  3. 00000000000000000000000000000111

异或运算

^ 操作符(异或),对应二进制位相同时,该位变成0,否则变成1

  1. int num1 = 5;
  2. int num2 = 9;
  3. printNum(num1);
  4. printNum(num2);
  5. printNum(num1 ^ num2);

结果如下:

  1. 00000000000000000000000000000101
  2. 00000000000000000000000000001001
  3. 00000000000000000000000000001100

左移

<< 操作(左移),二进制位向左移动,右边填充0

  1. int num1 = 5;
  2. printNum(num1);
  3. printNum(num1 << 2);

结果如下:

  1. 00000000000000000000000000000101
  2. 00000000000000000000000000010100

右移

>> 操作(右移),二进制位向右移动,左边填充0

  1. int num1 = 5;
  2. printNum(num1);
  3. printNum(num1 >> 2);

结果如下:

  1. 00000000000000000000000000000101
  2. 00000000000000000000000000000001

位运算的常见操作

不使用中间变量交换两个数

  1. int num1 = 2;
  2. int num2 = 5;
  3. num1 = num1^num2;
  4. num2 = num2^num1;
  5. num1 = num1^num2;
  6. System.out.println("num1:" + num1 +"\n"+ "num2:" + num2 );

求2的N次方

  1. //求2的32次方:
  2. System.out.println(Math.pow(2, 32));
  3. System.out.println(1L<<32);

判断奇数偶数

  1. int num1 = 4;
  2. int num2 = 9;
  3. if(num1%2 == 0){
  4. System.out.println("偶数");
  5. }else{
  6. System.out.println("奇数");
  7. }
  8. System.out.println((((int)num1&1) == 1) ? "奇数" : "偶数");
  9. System.out.println((((int)num2&1) == 1) ? "奇数" : "偶数");

绝对值

  1. int num = -3;
  2. System.out.println(Math.abs(num));
  3. int i = num >> 31;
  4. System.out.println(i == 0 ? num : (~num + 1));

计算某个正数的二进制表示法中 1 的个数

  1. //求解正数的二进制表示法中的 1 的位数
  2. private static int countBit(int num) {
  3. int count = 0;
  4. for(; num > 0; count++) {
  5. num &= (num - 1);
  6. }
  7. return count;
  8. }

获取某个数的第 i 位(判断某个数的第 i 位是0 还是 1?)

  1. //获取 整数 num 的第 i 位的值
  2. private static boolean getBit(int num, int i) {
  3. return ((num & (1 << i)) != 0);//true 表示第i位为1,否则为0
  4. }

将第 i 位设置为1

  1. //将 整数 num 的第 i 位的值 置为 1
  2. private static int getBit(int num, int i) {
  3. return (num | (1 << i));
  4. }

将第 i 位设置为0(清0)

  1. //将 整数 num 的第 i 位的值 置为 1
  2. private static int getBit(int num, int i) {
  3. int mask = ~(1 << i);//000100
  4. return (num & (mask));//111011
  5. }

参考内下内容:

  1. https://www.cnblogs.com/pear-lemon/p/4538244.html
  2. https://www.cnblogs.com/hapjin/p/5839797.html

评论

发表评论 点击刷新验证码

提示

该功能暂未开放