32 votes

La suppression d'un seul bit dans les indicateurs est-elle sûre avec les entiers de longueur variable Python?

Dans mon programme (écrit en Python 3.4) j'ai une variable qui contient divers drapeaux, donc par exemple:

FLAG_ONE = 0b1
FLAG_TWO = 0b10
FLAG_THREE = 0b100
status = FLAG_ONE | FLAG_TWO | FLAG_THREE

Le choix d'un autre indicateur peut être facilement fait avec

status |= FLAG_FOUR

Mais que faire si j'ai explicitement souhaitez effacer un drapeau? Je le ferais

status &= ~FLAG_THREE

Cette approche est-elle sûre? Comme la taille d'un entier en Python n'est pas définie, ce qui s' status et FLAG_THREE diffèrent par la taille?

(status doit être un champ de bits car j'ai besoin de cette valeur pour un matériel de protocole.)

16voto

ajcr Points 4047

Vous devriez être en sécurité à l'aide de cette approche, oui.

~ en Python est tout simplement mis en œuvre en tant que -(x+1) (cf. le Disponible de la source) et les nombres négatifs sont traités comme s'ils en ont le nombre requis de 1s rembourrage le début. À partir du Python Wiki:

Bien sûr, Python ne pas utiliser 8 bits. Il utilisait cependant nombre de bits natif de votre machine, mais depuis ce qui était non-portable, il a récemment opté pour l'utilisation d'un nombre INFINI de bits. Ainsi, le nombre -5 est traité par les opérateurs au niveau du bit comme si il avait été écrit "...1111111111111111111011".

En d'autres termes, avec au niveau du bit et & vous avez la garantie que ces 1s sera pavé de la longueur de l' ~FLAG (un entier négatif) à la longueur d' status. Par exemple:

  100000010000 # status
&       ~10000 # ~FLAG

est considérée comme

  100000010000
& 111111101111

= 100000000000 # new status 

Ce comportement est décrit dans un commentaire dans le source ici.

12voto

glglgl Points 35668

La compensation d'un indicateur fonctionne avec

status &= ~FLAG_THREE

parce que Python traite ceux annulés valeurs négatives:

>>> ~1L
-2L
>>> ~1
-2
>>> ~2
-3

Ainsi, l' & opérateur peut agir de manière appropriée et le rendement au résultat voulu, indépendamment de la longueur des opérandes, alors 0b11111111111111111111111111111111111111111111111111111111111 & ~1 fonctionne très bien même si l'opérande de gauche est biffer de la main droite une.

Dans l'autre direction (RH plus de LH), il fonctionne néanmoins, parce que d'avoir un trop grand nombre d' 1 bits n'a pas d'importance.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X