【算法】【位运算】一文带你搞懂位运算

二进制与十进制的转换

十进制->二进制

正整数

除二取余,逆序排列,高位补0
在这里插入图片描述

负整数

先是将对应的正整数转换成二进制后,对二进制取反,然后对结果再加一
在这里插入图片描述

小数

对小数点以后的数乘以2,然后取其结果的整数部分(不是1就是0),然后再用小数部分再乘以2,再取结果的整数部分……以此类推,直到小数部分为0或者位数已经够了就OK了。然后把取的整数部分按先后次序排列,就构成了二进制小数部分的序列

在这里插入图片描述

当小数除不尽的时候,一般取八位(或按要求)

混合数

在这里插入图片描述

二进制->十进制

正整数

从二进制的右边第一个数开始,每一个乘以2的n次方,n从0开始,每次递增1。然后得出来的每个数相加即是十进制数。

例如:

     二进制的数110化为十进制:

      0*2^0+1*2^1+1^2^2=6

负整数

如果补齐之后,最高位是1,则说明是负数

  • 方法一:先减一,再取反,再加上负号
  • 方法二:先取反,再加一,再加上负号

小数

在这里插入图片描述

在这里插入图片描述

原码、反码、补码的转换

(1) 正数的原码、反码、补码相同

(2) 负数的原码、反码、补码转换如下图所示

需要说明的是,在计算机中,数字是以补码的形式存在的,计算也是用补码来进行计算,计算后的结果也是补码

位运算

下表列出了位运算符的基本运算,假设整数变量 A 的值为 60 和变量 B 的值为 13:
在这里插入图片描述

(1) & : 按位与

5 & 9 = 1

(2) | : 按位或

5 | 9 = 13

(3) ^ : 按位异或

5 ^ 9 = 12

(4) ~ : 按位非

~5 = -6

(5) << : 左移

5 << 2 = 20

-5 << 2 = -20

(6) >> : 右移

-5 >> 2 = -2

(7) >>> : 无符号右移

-5 >>> 2 = 1073741822

应用

左移

左移常常被用来 *(2^n)的运算
8<< 1 -> 8 * 2=16
8<< 2 -> 8 * (2^2)=32
8<< n -> 8 * (2^n)

右移

右移常被用来做 / (2 ^ n)的运算,
12 >> 1 = 6
12 >> 2 = 3
12 >> n = 12 /(2^n)

位与

  • 二进制位与运算相当于对应位相加之后的进位 ,例如:

1 & 1 = 1 (当前位的值进一位)
1 & 0 = 0(当前位的值不进位)
0 & 0 = 0 (当前位的值不进位)

计算二进制中有多少个 1(32位)

x & (x-1)消去x最后一位知。循环使用x & (x-1)消去最后一位1,计算总共消去了多少次即可。
Loading Question… - 力扣(LeetCode)

public class Solution {  
    // you need to treat n as an unsigned value  
    public int hammingWeight(int n) {  
        int count = 0;  
        for (int i = 0; i < 32; ++i) {  
            count += n & 1;  
            n >>>= 1;  
        }  
        return count;  
  
    }  
  
    public int hammingWeight2(int n) {  
        int res = 0;  
        while (n != 0) {  
            res += 1;  
            n &= n - 1;//可以把n的最后一个1变成0  
        }  
        return res;  
    }  
  
}

取模运算转化成位运算

(在不产生溢出的情况下)

  • a % (2^n)等价于a & (2^n - 1)

  • a % 2等价于a & 1

判断奇偶数

利用 &位运算符的特性,判断二进制数第一位是0还是1。
if ((a & 1) == 0) 代替if (a % 2 == 0)来判断a是不是偶数。

异或

  • 二进制位的异或运算相当于位相加,例如:

1 ^ 1 = 0 (当前位值为 0 进一位)
1 ^ 0 = 1 (当前位值为 1)
0 ^ 0 = 0 (当前位值为 0)

交换两个数

使用 ^位运算符的特性,不使用临时变量实现两个数的交换。

a ^= b;
b ^= a;
a ^= b;

a=10,b=1
a=11
b=10
a=1

eg a=10,b=10,c=a^b=0,可以实现相加的效果,但是没有进位的效果

因此 ^ & <<可以一起实现+的效果
题目链接

public int add(int a, int b) {  
    while(b != 0){  
        int temp = a ^ b;//计算出相对应的位置相加后的结果,非进位和  
        b = (a & b) << 1;//计算出想对应的位置的进位,然后左移一位  
        a = temp;  
    }  
    return a;  
}

LeetCode

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值