Sie können keinen Python wechseln int
von positiv auf negativ den Weg zu Sie versuchen, nur um ein wenig in seiner Darstellung Spiegel. Sie nehmen an, dass es in einer Zweierkomplementdarstellung fester Länge gespeichert ist. Aber Integer in Python 3 sind keine Bitfolgen fester Länge, und sie werden nicht in einer Zweierkomplementdarstellung gespeichert. Stattdessen werden sie als Strings mit variabler Länge von 30- oder 15-Bit- "Ziffern" gespeichert, wobei das Zeichen separat gespeichert wird (z. B. signed-magnitude representation). Also die "niedrigste" Möglichkeit, ein Python int
zu negieren, ist nicht mit Bit-Operationen, sondern mit dem unären -
-Operator, der sein Vorzeichen wechselt. (Siehe Ende dieser Antwort für Details aus der Python-3-Quelle.)
(Ich sollte auch erwähnen, dass sys.getsizeof()
tut nicht Ihnen sagen, die Anzahl der Bits in Ihrem int
. Es gibt Ihnen die Anzahl von Bytes des Speichers ., dass die integer-Objekt wird mit diesem auch nicht die Anzahl der Bytes der tatsächlichen gespeicherten Nummer ist, die meisten dieser Bytes sind für andere Dinge)
Sie noch mit Zweierkomplement-Darstellungen in Python rumspielen kann. durch Emulieren einer Bitfolge fester Länge unter Verwendung einer positiven int
. Wählen Sie zunächst die gewünschte Länge aus, z. B. 6 Bits. (Sie können nur wählen, wie leicht größere Zahlen wie 28 oder 594.) Wir können einige hilfreiche Konstanten und Funktionen definieren:
BIT_LEN = 6
NUM_INTS = 1 << BIT_LEN # 0b1000000
BIT_MASK = NUM_INTS - 1 # 0b111111
HIGH_BIT = 1 << (BIT_LEN - 1) # 0b100000
def to2c(num):
"""Returns the two's complement representation for a signed integer."""
return num & BIT_MASK
def from2c(bits):
"""Returns the signed integer for a two's complement representation."""
bits &= BIT_MASK
if bits & HIGH_BIT:
return bits - NUM_INTS
Jetzt können wir etwas tun, wie Sie versuchen zu:
>>> x = to2c(2)
>>> x |= 1 << 5
>>> bin(x)
'0b100010'
>>> from2c(x)
-30
Welche zeigt, dass das Einschalten des High-Bits für die Zahl 2 in einer 6-Bit-Zweierkomplementdarstellung die Zahl in -30 umwandelt.Dies macht Sinn, denn 2 6-1 = 32, also ist die niedrigste ganze Zahl in dieser Darstellung -32. Und -32 + 2 = -30.
Wenn Sie in den Details interessiert sind, wie Python 3 speichert ganze Zahlen Sie durch Objects/longobject.c in der Quelle suchen. Insbesondere Blick auf the function _PyLong_Negate()
:
/* If a freshly-allocated int is already shared, it must
be a small integer, so negating it must go to PyLong_FromLong */
Py_LOCAL_INLINE(void)
_PyLong_Negate(PyLongObject **x_p)
{
PyLongObject *x;
x = (PyLongObject *)*x_p;
if (Py_REFCNT(x) == 1) {
Py_SIZE(x) = -Py_SIZE(x);
return;
}
*x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x));
Py_DECREF(x);
}
Sie können sehen, dass alle es im Normalfall macht, ist die Py_SIZE()
Wert des ganzzahligen Objekt negieren. Py_SIZE()
ist einfach eine Referenz auf das Feld ob_size
des Integer-Objekts. Wenn dieser Wert 0 ist, ist die Ganzzahl 0. Andernfalls ist das Vorzeichen das Vorzeichen der Ganzzahl und der absolute Wert ist die Anzahl der 30- oder 15-Bit-Ziffern im Array, die den absoluten Wert der Ganzzahl enthalten.
Wenn man bedenkt, dass 'bin (5)' '' 0b101'' zurückgibt, welches Bit möchten Sie umdrehen? –
Beachten Sie auch, dass sys.getsizeof (x) die Größe in Bytes und nicht in Bits zurückgibt. – Schore
Ich möchte nur das Vorzeichen Bit (um es negative Zahl machen) – Hypnoz