学习记录5——Java位运算


一、位运算的概念

现代计算机中所有的数据二进制的形式存储在设备中,非0即1。对二进制数据进行的运算(+、-、*、/)都是叫位运算,即将符号位共同参与运算的运算。

二、位运算过程

在计算机中运算是以二进制来进行,如下面所示的计算两数之和:

int a = 10;
int b = 12;
int c = a + b;

计算机在进行运算时,会先将 int型变量先转换成二进制形式再进行运算:

a   10:  0 0 0 0 1 0 1 0
b   12:  0 0 0 0 1 1 0 0
—————————————————————————————
c   22:  0 0 0 1 0 1 1 0

三、位运算类型

符号描述运算规则
&两个位都为1才为1,否则为0
I两个位都为0才为0,否则为1
^异或相同为0,不同为1
~取反0变1,1变0
<<左移各位都向左进行移位操作,高位丢弃,低位补0(左移一位,相当于乘2,移两位相当于乘2*2,n位为乘2的n次方)
>>右移各位都向右进行移位操作,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)(右移一位,相当于除2,右移n位,相当于除2的n次方

四、实际运用

  1. 清零
    如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。
    即xxxxxxxxxx&0=0
  2. 取一个数的指定位
    比如取数 X=1010 1110 的低4位,只需要另找一个数Y,令Y的低4位为1,其余位为0,即Y=0000 1111,然后将X与Y进行按位与运算(X&Y=0000 1110)即可得到X的指定位。
  3. 判断数a的奇偶性
 if((a&1)==1){
    //a是奇数(因为奇数二进制末位为1,两位为1,与结果为1)
}
 if((a&1)==0){
    //a是偶数(因为偶数二进制末位为0,与结果为0)
  1. 判断数a的二进制中第n位为是否为1
  if((a&(1<<(n-1)==0){
    //a的二进制数第n位为0(利用与的运算规则,将1左移到要检测的位置,第n位要从第一位移动(n-1)位)
  }else{
    //a二进制数第n位为1
    }
  1. 交换两个数(无需第三个数即中间数)
    首先需要了解异或的性质
    1交换律: a ^ b = b ^ a
    2结合律: a ^ (b ^ c)=(a ^ b) ^ c
    3 a ^ a=0 , a ^ 0=a
public class Test {
    public static void swap(String[] args) {
        int x =1;int y = 2;
        x=x^y;
        y=x^y;
        x=x^y;
        System.out.println("交换后"+x+" "+y);
    }
}
  1. 给一组整形数据,这些数据中,其中有一数只出现了一次,其他数据都出现了两次,找出只出现一次的数
 public class Test {
    public static int getSingle(int[] nums) {
   //如给定一个数组[1,2,5,1,2]
   //常规解法:
   //从一个任意的数组中找出只出现了一次的数,需要遍历数组,将数字出现的次数计数,最后返回计数为1的数字
   //异或思路:使用性质: a ^ a=0,遍历数组,将每个数字进行异或累积
   // 1^2^5^1^2=(1^1)^(2^2)^5=0^0^5=5
  for (int i = 0; i < nums.length; ++i) {
            single ^= nums[i];
        }
     return single;
  }
  1. 两个整数相加
    两数异或可以视作不进位的加和,在加和中只有当两数对应位都为1的情况下才会产生进位,而对应位都为1在与(&)的结果下都为1,再左移一位用来表示进位,那么a+b=(a^b)+(a&b)<<1
 int a=12,b=10;
 a      1100           1100          1100 
 b    ^ 1010         & 1010        + 1010
 ————————————————————————————————————————————
c       0110           1000         10110

此题来源于力扣(LeetCode),如下面题目要求所示,不能使用运算符+和-
在这里插入图片描述

class Solution {
    public int add(int a, int b) {
      return b==0?a:add(a^b,(a&b)<<1);
    }
}

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值