简体   繁体   English

翻转python中的位

[英]Flipping bits in python

Given an integer n , i want to toggle all bits in the binary representation of that number in the range say lower to upper. 给定一个整数n,我想切换该数字的二进制表示中的所有位,从低到高。 To do this i do the following [bit_string is a string containing 1's and 0's and is a binary representation of n] 为此,我执行以下操作[bit_string是一个包含1和0的字符串,是n的二进制表示]

for i in range(lower,upper+1):
   n ^= (1 << len(bit_string)-1-i) #Toggle the ith bit

Then , i also need to determine that given a range, say lower to upper,how many bits are set.My code to do that is as follows : 然后,我还需要确定给定一个范围,比如从低到高,设置了多少位。我的代码如下:

number_of_ones = 0
for i in range(lower,upper+1):
    if(n & (1 << len(bit_string)-1-i)): #Check the ith bit
      number_of_ones+=1

But, if n is very large, i think these algorithms would be slow. 但是,如果n非常大,我认为这些算法会很慢。 Is there a way to make these two operations faster/more efficient ? 有没有办法让这两项操作更快/更有效?

Thank You 谢谢

For the "flipping", you can make a single bitmap (with ones in all positions of interest) and a single exclusive-or: 对于“翻转”,您可以制作单个位图(包含所有感兴趣位置的位图)和单个独占 - 或:

n ^= ((1<<upper)-1)&~((1<<lower)-1)

For bit-counts, once you isolate (n & mask) for the same "mask" as the above RHS, slicing it into eg 8-bit slices and looking up the 8-bit counts in a lookup table (just a simple list or array.array to prepare beforehand) is about the fastest approach. 对于位计数,一旦您为与上述RHS相同的“掩码”隔离(n和掩码),将其切换为例如8位片并在查找表中查找8位计数(只是一个简单的listarray.array事先准备)是最快的方法。

gmpy has some useful and speedy bit-manipulation and counting operations, esp. gmpy有一些有用且快速的位操作和计数操作,尤其是 faster than Python's native offerings if you're dealing with very long bit strings (more than a machine word's worth, so in Python they'd be long instances). 如果你处理非常长的字符串(超过机器字的价值,那么比Python的原生产品更快),所以在Python中它们是long实例。

def bitflip(n,range):
    bitfliplen = range[1]-range[0]
    return n ^ ((2**bitfliplen-1) << (range[0]))

Running: 运行:

>>> a = 47727124L
>>> b = bitflip(a,(5,10))
>>> print "a: {0:b}\nb: {1:b}".format(a,b)
a: 10110110000100001000010100
b: 10110110000100000111110100
>>>

For bit counting, once you've masked out the range you are interested in, see the bitCount() routine on the python BitManipulation wiki page which implements Brian Kernighan's scheme: 对于位计数,一旦你屏蔽了你感兴趣的范围,请参阅python BitManipulation wiki页面上的bitCount()例程,它实现了Brian Kernighan的方案:

def bitCount(int_type):
    count = 0
    while(int_type):
        int_type &= int_type - 1
        count += 1
    return(count)

I don't know python so I am just thinking this from a pure mathsy agorithmy point of view... 我不知道python所以我只是从一个纯粹的数学观点来看这个......

It occurs to me that for the first part a more efficient method might be to construct a mask of the bits you want to switch first as an integer. 在我看来,对于第一部分,一个更有效的方法可能是构造一个你想首先作为整数切换的位的掩码。 To make life easy for me I'm going to assume that you are counting your lower and upper bounds from the least significant bit being 0 and the most significant being 31 (or whatever is appropriate for the length of an int in your case). 为了让生活变得简单,我将假设你从最低有效位为0计算你的下限和上限,最重要的是31(或者你的情况下适合int的长度)。

If you want bits n to m (m>n) to be flipped then the binary representation of the number 2^(m+1)-2^n will have these bits set. 如果希望翻转位n到m(m> n),则数字2 ^(m + 1)-2 ^ n的二进制表示将设置这些位。 Then do an XOR and you do all the swaps in one go. 然后进行异或,你可以一次性完成所有交换。 The computer should be abel to do these in one go probably rather than one per bit swap. 计算机应该可以一次性完成这些操作,而不是每位交换一次。

As for the counting I'm not sure. 至于计数,我不确定。 There are ways to count the number of set bits in a number. 有一些方法可以计算一个数字中的设置位数。 I'm not sure if you get a gain in efficiency to use the above bitmask with an AND to 0 out all the bits you don't care about counting nad then use those algorithms or if you are best off modifying them to work for you. 我不确定你是否可以获得效率提升,使用上面的位掩码和一个AND来计算你不关心计算nad的所有位然后使用这些算法,或者你最好修改它们为你工作。 I dont' know how they work off the top of my head though. 我不知道他们是如何工作的。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM