神奇的按位运算(python)

先来看LeetCode-29上的Divide Two Integers题目要求:

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

就是说不用乘法,除法,求模运算来实现两个整数相除。如果溢出,返回MAX_INT。看起来很简单,我可以用除数减去被除数,直到除数小于被除数,记录减法操作的次数即可。假设是计算m/n,那么时间复杂度为O(m/n)。用Python实现后,Time Limit Exceeded。我们考虑有没有更加优化的算法呢?

如果很难想得到,那就先来回忆下二进制数按位运算的一些知识。

二进制数按位运算

计算机里面所有数据都存储为0,1串,所有的运算归根到底都转为二进制数的运算。相信大家都知道二进制数按位运算的规则:
这里写图片描述

来看一些简单的例子:

1010 & 1100 = 1000
1010 | 1100 = 1110
1010 ^ 1100 = 0110
1010 << 2 = 101000
1010 >> 2 = 10
~1010 = 0101

单纯的二进制位之间的这些运算相当简单,但对我们实际编程并没有直接帮助,因为编程过程中需要的经常是数字间的运算,比如 5*(2^4) 。真的是这样吗?接着往下看!

计算机中数字的存储方式

我们都知道计算机中万物皆为0、1,将万物变为0、1的过程叫做编码,这里我们只讨论将数字编码为0、1的过程。

计算机中对数字的表示有三种方式:原码,反码,补码

  • 原码:原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1。比如十进制3如果用8个二进制位来表示就是 00000011, -3就是 10000011。

  • 反码:反码表示方法:正数的反码是其本身;负数的反码是在其原码的基础上,符号位不变,其余各个位取反。

  • 补码:补码表示方法:正数的补码是其本身;负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1。 (即在反码的基础上+1)

原码容易被人脑直接识别并用于计算,但是对于计算机来说并不友好。所以在计算机系统中,数值一律用补码来表示、运算和存储。使用补码,可以将符号位和数值域统一处理,将加法和减法统一处理。此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

数字的按位运算

计算机中数字存储为补码形式,各个数之间的运算也是对它们的补码做运算,而且得到的结果也是补码,如下图:
这里写图片描述

各种编程语言都提供了对补码的二进制位直接进行运算的方法。以Python为例:

这里写图片描述
上面0b开头的0、1串表示整型数字,在32位操作系统中,Python中int类型一般占32个二进制位,以最后一个求反运算为例子,1010的补码为

00000000 00000000 00000000 00001010

求反操作后为:

11111111 11111111 11111111 11110101

即为-11(原码为:10000000 00000000 00000000 00001011)的补码。(对一个数的补码求补码即可得到该数的原码)

另辟蹊跷的按位运算

那么按位运算在实际编程中可以扮演哪些角色呢?简单点地,可以用来判断奇、偶数:num & 0x1,或者对一个数变换符号:~num + 1;复杂点的可以用来交换两个数,求绝对值等等。
1、 不用额外的变量实现两个数字互换。

# coding: utf-8
def swap(num_1, num_2):
    num_1 ^= num_2
    num_2 ^= num_1
    num_1 ^= num_2
    return num_1, num_2

num1 = 5
num2 = 3
print u'交换前','----',num1, num2
num1, num2 = swap(num1, num2)
print u'交换后','----',num1, num2

证明很简单,我们只需要明白异或运算满足下面规律:

0^a=a
a^a=0
a^b^c=a^c^b

巧妙运用异或可以高效解决很多问题,比如 找出数组中只出现了一次的数(除了一个数只出现一次外,其他数都是出现两次),以及它的升级版:数组中只出现1次的两个数字(百度面试题)。
2、 不用判断语句来实现求绝对值。

def bit_abs(value):
    return (value ^ (value >> 31)) - (value >> 31)

print(bit_abs(-100))

猜你喜欢

转载自blog.csdn.net/qq_36653505/article/details/81871359