2010-07-11 9 views
2

Disons que j'ai deux entiers avec les représentations binaires suivantes:Comment copier les X derniers bits?

01101010 
00110101 

Et maintenant, je veux copier les 3 derniers bits du premier entier sur le second afin qu'il devienne

00110010 

Quelle est la meilleure façon de faire cela? (En fait, mon objectif est de déplacer tous les bits X + 1 vers la droite, en supprimant essentiellement le Xe bit, et en gardant les bits X-1 identiques - dans ce cas, X est 4)


Le "pourquoi?":

vous avez un tas de drapeaux,

1 = 'permission x' 
2 = 'permission y' 
4 = 'permission z' 
8 = 'permission w' 

vous décidez que que "l'autorisation y" n'est plus nécessaire que vous r, et déplace ainsi z et w vers le haut (en les faisant respectivement 2 et 4). Cependant, maintenant vous devez mettre à jour toutes les valeurs dans votre base de données .... (quelle formule utilisez-vous?)

Répondre

8

Selon votre version de python, la façon dont vous exprimez les modifications de littéraux binaires, voir this question for the details.

J'utilise 2.5.2, donc j'utilisé ceci:

>>> a = int('01101010', 2) 
>>> b = int('00110101', 2) 
>>> mask = 07 # Mask out the last 3 bits. 
>>> (b & ~mask) | (a & mask) 
50 
>>> int('00110010', 2) 
50 

Détails:

(b & ~mask) <- This keeps the first n-3 bits. (By negating the 3bit mask). 
(a & mask) <- This keeps the last 3 bits. 
If you '|' (bitwise OR) them together, you get your desired result. 

Je ne comprends pas votre but dans la dernière phrase , donc je ne sais pas comment aborder ça :)

+0

Plus généralement, 'mask = (1 << (x-1)) - 1' Je pense? – mpen

+0

@Mark: Bon appel, j'ai été confus par le '3' vs '4' vs 'X + 1', mais je pense que vous avez raison. – Stephen

+0

Bien "4" est le bit à "supprimer". Ce qui signifie que nous devons garder les bons «3» bits identiques. – mpen

2

Basé sur Step réponse de poule (upvote lui), la solution est:

def f(pos, val): 
    """ 
    @pos: the position of the bit to remove 
    @val: the value to remove it from 
    """ 
    mask = (1<<(pos-1))-1 
    return ((val>>1) & ~mask) | (val & mask) 

print f(4, int('01101010', 2)) == int('00110010', 2)