En Complément à deux Binaires en Python?
Entiers en Python sont stockés en complément à deux, correct?
Bien:
>>> x = 5
>>> bin(x)
0b101
Et:
>>> x = -5
>>> bin(x)
-0b101
C'est assez boiteux. Comment puis-je obtenir python pour me donner les chiffres RÉELS chiffres binaires, et sans la 0b en face d'elle? Donc:
>>> x = 5
>>> bin(x)
0101
>>> y = -5
>>> bin(y)
1011
- Comment il est stocké est un détail d'implémentation.
- Merci Deux, c'est très gentil à vous!
- double possible de en complément à deux de nombres en python
Vous devez vous connecter pour publier un commentaire.
Pas sûr de la façon d'obtenir ce que vous voulez en utilisant la lib standard. Il y a une poignée de scripts et logiciels qui permettra de faire la conversion pour vous.
Je voulais juste note le "pourquoi" , et pourquoi il n'est pas boiteux.
bin() ne retourne pas les bits binaires. il convertit un nombre en une chaîne binaire. le début "0b", dit à l'interprète que vous avez à traiter avec un nombre binaire en nombre , comme par le langage python définition. de cette façon, vous pouvez travailler directement avec des nombres binaires, comme ce
ce n'est pas boiteux. c'est très bien.
http://docs.python.org/library/functions.html#bin
http://docs.python.org/reference/lexical_analysis.html#integers
Il fonctionne mieux si vous fournissez un masque. De cette façon, vous spécifiez la façon dont la mesure de signer étendre.
Ou peut-être de manière plus générale:
Dans la théorie de base, la largeur réelle de la le nombre est fonction de la taille de l'espace de stockage. Si c'est un nombre de 32 bits, puis un nombre négatif a un 1 dans le bit de poids fort d'un jeu de 32. Si c'est une valeur 64 bits, alors il y a 64 bits pour l'affichage.
Mais en Python, entier précision est limitée seulement aux contraintes de votre matériel. Sur mon ordinateur, ce fonctionne réellement, mais il consomme 9GO de RAM juste pour stocker la valeur de x. Quelque chose de plus élevé et je reçois un MemoryError. Si j'avais plus de RAM, je pourrais stocker un plus grand nombre.
Donc, avec cela à l'esprit, ce nombre binaire représente
-1
? Python est bien capable d'interpréter littéralement des millions (et même des milliards) de bits de précision, comme l'exemple précédent le montre. En complément de 2, le bit de signe s'étend tout le chemin à gauche, mais en Python il n'y a pas de pré-définir le nombre de bits; il y en a autant que vous avez besoin.Mais puis que vous exécutez dans l'ambiguïté: est-ce binaire
1
représentent1
, ou-1
? Eh bien, il pourrait être. Ne111
représentent7
ou-1
? Encore une fois, il pourrait être. Donc ne111111111
représentent511
, ou-1
... eh bien, à la fois, en fonction de votre précision.Python a besoin d'un moyen de représenter ces nombres en binaire, de sorte qu'il n'y a aucune ambiguïté de leur sens. Le
0b
préfixe juste dit "ce nombre est en binaire". Tout comme0x
signifie "ce nombre est en hexadécimal". Donc si je dis0b1111
, comment puis-je savoir si l'utilisateur veut -1 ou 15? Il y a deux options:Option A: Le bit de signe
Vous pouvez déclarer que tous les nombres sont signés, et le plus à gauche bit est le bit de signe. Cela signifie que
0b1
est -1, tandis que0b01
est 1. Cela signifie aussi que0b111
est également -1, tandis que0b0111
est 7. En fin de compte, ce n'est probablement plus à confusion qu'utile en particulier parce que la plupart des arithmétique binaire va être unsigned de toute façon, et les gens sont plus susceptibles d'exécuter des erreurs par inadvertance en marquant un nombre négatif parce qu'ils n'ont pas prévoir de façon explicite le bit de signe.Option B: Le signe indication
Avec cette option, les nombres binaires sont représentées non signés, et les nombres négatifs ont un "-" préfixe, comme ils le font en décimal. C'est (un) plus cohérente avec décimale, (b) plus compatible avec la manière dont les valeurs binaires sont les plus susceptibles va être utilisé. Vous perdez la possibilité de spécifier un nombre négatif à l'aide de son complément à deux de la représentation, mais n'oubliez pas qu'en complément à deux est un de stockage de la mise en œuvre détail, pas une bonne indication de la valeur sous-jacente elle-même. Cela ne devrait pas être quelque chose que l'utilisateur a à comprendre.
En fin de compte, l'Option B qui fait le plus de sens. Il y a moins de confusion et l'utilisateur n'est pas nécessaire pour comprendre le stockage de détails.
-27 & 0b111111111
est un nombre positif en mémoire!)-27 & 0b11111111
est un zéro. (Plus généralement, le résultat de&
sera toujours positif si l'un des opérandes est positive, car une valeur positive est entendu à être précédée par un infini chaîne de zéros.)bin(-12 & int('0b' + '1' * 16, 2))
pour les paresseux.bin(-9 & 0b11111)
. et obtenir0b10111
.Pour interpréter correctement une séquence binaire comme complément à deux, il faut une longueur associée à la séquence. Lorsque vous travaillez de bas niveau des types qui correspondent directement aux registres du CPU, il y a un implicite de la longueur. Depuis Python entiers peuvent avoir une longueur arbitraire, il n'est pas vraiment un interne en complément à deux format. Puisqu'il n'y a pas une longueur associée à un certain nombre, il n'y a aucun moyen de distinguer entre les nombres positifs et négatifs. Pour supprimer l'ambiguïté, bin() inclut un signe moins lors du formatage d'un nombre négatif.
Python longueur arbitraire de type entier utilise en fait un signe de magnitude format interne. Les opérations logiques (décalage de bits, et, ou, etc.) sont conçus pour imiter le complément à deux de format. C'est typique de plusieurs de précision bibliothèques.
par exemple
Ou désactivez les fonctions:
(Adapté de W. J. Van de Laan du commentaire)
Je ne suis pas entièrement sûr de ce que vous voulez finalement à le faire, mais vous pourriez vouloir regarder le bitarray paquet.
Utiliser des tranches de se débarrasser des indésirables '0b'.
ou si vous voulez des chiffres,
ou même
Pour les nombres positifs, il suffit d'utiliser:
Pour les nombres négatifs, c'est un peu différent:
Comme un ensemble de script, c'est comment il devrait ressembler à:
1011
, pas101
.binary(-4)
doit être quelque chose comme1100
ou11111100
, mais cela donne11
, ce qui est totalement faux.Une modification sur tylerl est très utile de répondre à cette offre l'extension du signe pour les nombres positifs et négatifs (pas de contrôle d'erreur).
Exemple:
Pas besoin, elle ne l'est déjà. C'est juste python qui choisissent de se représenter les choses différemment. Si vous lancez l'impression, chaque grignoter séparément, il va montrer ses vraies couleurs.
De sortie est simple:
Maintenant, il revient à l'origine de la représentation lorsque vous souhaitez afficher un complément à deux de grignoter, mais il est encore possible si vous le divisez en deux moitiés de grignoter et ainsi de. Juste avoir à l'esprit que le meilleur résultat est négatif hexadécimal et en binaire entier interprétations chiffres simples pas tellement, aussi avec hex vous pouvez définir la taille en octets.
Ici est un peu plus lisible que la version de Tylerl répondre, par exemple, disons que vous voulez -2 dans son 8-bits représentation négative de "complément à deux" :
2**8 représente le neuvième bit (256), il suffit de soustraire 1 et vous avez toutes les précédentes bits à un (255)
pour 8 et 16 bits masques, vous pouvez remplacer (2**8-1) par 0xff, ou 0xffff. Le code hexadécimal de la version devient de moins en moins readalbe après ce point.
Si ce n'est pas clair, ici, est une fonction régulière de celui-ci:
J'espère que cela résout votre problème`