Wie verwaltet Python int und long?

118

Weiß jemand, wie Python intern int und long-Typen verwaltet?

  • Wählt es dynamisch den richtigen Typ?
  • Was ist die Grenze für ein int?
  • Ich verwende Python 2.6. Ist es anders als in früheren Versionen?

Wie soll ich den folgenden Code verstehen?

>>> print type(65535)
<type 'int'>
>>> print type(65536*65536)
<type 'long'>

Aktualisieren:

>>> print type(0x7fffffff)
<type 'int'>
>>> print type(0x80000000)
<type 'long'>
luc
quelle
Werden sie nicht einfach im laufenden Betrieb in CPython stdc-Typen zugeordnet?
Aiden Bell
Ja, ich denke sie tun es. Ich vermute auch, dass alles auf dem Heap zugeordnet ist. Wenn also eine Zahl präziser sein reallocmuss, ist alles in Ordnung. Aber ich bin mir nicht ganz sicher, also überlasse ich die Antwort jemand anderem.
Zneak
2
Sie können Python auch zwingen, lange Variablen mitvar = 666L
qba
8
@Ignacio: FALSCH Ein CPython intist ein C long(Standard ist signiert) ... siehe <CPython 2.X source>/Include/intobject.h: typedef struct {PyObject_HEAD long ob_ival; } PyIntObject; In jedem Fall interlaubt Python 2.x negative Zahlen; ein C unsignedwürde einfach nicht fertig werden.
John Machin
In PEP 237 wird diskutiert, wie Python unter der Haube alles scheinbar gleich machen soll.
Carel

Antworten:

123

intund longwurden vor ein paar Versionen "vereinheitlicht" . Zuvor war es möglich, ein Int durch Math Ops zu überlaufen.

3.x hat dies weiter vorangetrieben, indem es long insgesamt eliminiert und nur int hat.

  • Python 2 : sys.maxintEnthält den Maximalwert, den ein Python-Int enthalten kann.
    • Auf einem 64-Bit-Python 2.7 beträgt die Größe 24 Byte. Überprüfen Sie mit sys.getsizeof().
  • Python 3 : sys.maxsizeEnthält die maximale Größe in Bytes, die ein Python-Int haben kann.
    • Dies sind Gigabyte in 32 Bit und Exabyte in 64 Bit.
    • Ein so großes int hätte einen Wert ähnlich 8 hoch der Potenz von sys.maxsize.
Ignacio Vazquez-Abrams
quelle
29
Aber Python3 nennt diesen Typ 'int', obwohl er sich eher wie 'long' von 2.x verhält.
3
Kommentar von Ted: Wie unten erwähnt, ist zu beachten, dass das Umwandeln von etwas in int, das größer als maxint ist, immer noch zu einem langen >>> Typ (int (sys.maxint + 1)) <Typ 'long'> führt
StuartLC
2
sys.maxint gibt Ihnen die größte 64-Bit-Ganzzahl (auf meinem 64-Bit-Computer). Ein Long kann viel größer als 64-Bit sein. Versuchen Sie einfach "sys.maxint << 1000000"
fccoelho
4
In Python3 ist es sys.maxsize
Pylover
3
sys.maxsize hat nichts mit ganzen Zahlen zu tun. Die sys.maxint von Python 3 wurde entfernt, da es keine maximale Größe für eine Ganzzahl gibt (Python 3 entspricht intPython 2 long).
Asmeurer
19

Dieser PEP sollte helfen.

Fazit ist, dass Sie sich in Python-Versionen> 2.4 wirklich keine Sorgen machen müssen

mluebke
quelle
15
Sie müssen sich darüber Sorgen machen, wenn Sie eine int-Funktion in c mit etwas aufrufen müssen, das nicht in int passt (dh eine lange). Keine Menge an Casting Long-> Int wird helfen. Ist mir erst kürzlich passiert.
Macke
1
@ Macke: Dieser Kommentar hat mich gerettet, ich nahm an, dass int den Trick machen würde, und fragte mich, warum ich immer noch eine Jython-Ausnahme bekam.
Ted
@ Macke Absolut wahr. In der Firma, in der ich derzeit arbeite, haben wir einen in Python geschriebenen Simulator, der Benutzereingaben über Tkinter-Einträge entgegennimmt und die umgesetzten Werte über TCP / IP an einen Client (geschrieben in C / C ++) sendet, der ein eingebettetes System nachahmt. Stellen Sie sich vor, was passiert, wenn Sie 100000000000000000000000 in Ihren Python-basierten Eintrag einfügen ...: P
rbaleksandar
@ Mackie gut, wenn Sie sich tatsächlich die Mühe gemacht haben, das PEP zu lesen, heißt es ausdrücklich: Die C-API bleibt unverändert; C-Code muss sich immer noch des Unterschieds zwischen kurzen und langen Ints bewusst sein. (Die Python 3.0 C-API wird wahrscheinlich vollständig inkompatibel sein.) Die PyArg_Parse * () -APIs akzeptieren bereits lange Ints, solange sie innerhalb des Bereichs liegen, der durch C-Ints oder Longs dargestellt werden kann, sodass Funktionen mit C int oder langen Argumenten gewonnen werden. ' Sie müssen sich keine Gedanken über den Umgang mit Python Longs machen.
Cowbert
4

Auf meiner Maschine:

>>> print type(1<<30)
<type 'int'>
>>> print type(1<<31)
<type 'long'>
>>> print type(0x7FFFFFFF)
<type 'int'>
>>> print type(0x7FFFFFFF+1)
<type 'long'>

Python verwendet Ints (32-Bit-Ganzzahlen mit Vorzeichen, ich weiß nicht, ob es sich um C-Ints unter der Haube handelt oder nicht) für Werte, die in 32-Bit passen, wechselt jedoch automatisch für alles zu Longs (beliebig große Anzahl von Bits - dh Bignums) größer. Ich vermute, dass dies die Dinge für kleinere Werte beschleunigt und gleichzeitig Überläufe mit einem nahtlosen Übergang zu Bignums vermeidet.

MAK
quelle
4

Interessant. Auf meiner 64-Bit-Box (i7 Ubuntu):

>>> print type(0x7FFFFFFF)
<type 'int'>
>>> print type(0x7FFFFFFF+1)
<type 'int'>

Vermutlich werden auf einem größeren Computer bis zu 64-Bit-Ints angezeigt.

Gringo Suave
quelle
2
Python verwendet den größeren Integer-Typ, der für die Maschine verfügbar ist. Auf 32-Bit-Computern hat int normalerweise eine 32-Bit-Größe, während es auf 64-Bit-Computern eine 64-Bit-Größe hat. Es könnte jedoch 32-Bit-Architekturen geben, die 64-Bit-Ganzzahlen definieren. In diesem Fall würde Python die 64-Bit-Ganzzahl verwenden.
Bakuriu
4

Python 2.7.9 fördert automatisch Zahlen. Für einen Fall, in dem man sich nicht sicher ist, int () oder long () zu verwenden.

>>> a = int("123")
>>> type(a)
<type 'int'>
>>> a = int("111111111111111111111111111111111111111111111111111")
>>> type(a)
<type 'long'>
nvd
quelle
4

Python 2 legt den Typ automatisch basierend auf der Größe des Werts fest. Eine Anleitung mit Maximalwerten finden Sie unten.

Der Maximalwert des Standard-Int in Python 2 ist 65535, alles, was darüber liegt, ist lang

Beispielsweise:

>> print type(65535)
<type 'int'>
>>> print type(65536*65536)
<type 'long'>

In Python 3 wurde der lange Datentyp entfernt und alle ganzzahligen Werte werden von der Int-Klasse behandelt. Die Standardgröße von Int hängt von Ihrer CPU-Architektur ab.

Beispielsweise:

  • 32-Bit-Systeme Der Standarddatentyp für Ganzzahlen ist "Int32".
  • 64-Bit-Systeme Der Standarddatentyp für Ganzzahlen ist "Int64".

Die Min / Max-Werte der einzelnen Typen finden Sie unten:

  • Int8: [-128,127]
  • Int16: [-32768,32767]
  • Int32: [-2147483648,2147483647]
  • Int64: [-9223372036854775808,9223372036854775807]
  • Int128: [-170141183460469231731687303715884105728,170141183460469231731687303715884105727]
  • UInt8: [0,255]
  • UInt16: [0,65535]
  • UInt32: [0,4294967295]
  • UInt64: [0,18446744073709551615]
  • UInt128: [0,340282366920938463463374607431768211455]

Wenn die Größe Ihres Int die oben genannten Grenzwerte überschreitet, ändert Python automatisch seinen Typ und weist mehr Speicher zu, um diese Erhöhung der Min / Max-Werte zu bewältigen. Wo es in Python 2 in 'long' konvertiert wird, wird es jetzt nur noch in die nächste Größe von Int konvertiert.

Beispiel: Wenn Sie ein 32-Bit-Betriebssystem verwenden, beträgt Ihr Maximalwert für ein Int standardmäßig 2147483647. Wenn ein Wert von 2147483648 oder höher zugewiesen wird, wird der Typ in Int64 geändert.

Es gibt verschiedene Möglichkeiten, die Größe des int und seine Speicherzuordnung zu überprüfen. Hinweis: In Python 3 gibt die Verwendung der integrierten type () -Methode immer zurück, <class 'int'>unabhängig von der Größe, die Sie verwenden.

James Lane
quelle
1

Ab Python 3.x sind die einheitlichen Integer-Bibliotheken noch intelligenter als ältere Versionen. Auf meiner (i7 Ubuntu) Box habe ich folgendes:

>>> type(math.factorial(30))
<class 'int'>

Einzelheiten zur Implementierung finden Sie in den Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.cDateien. Die letzte Datei ist ein dynamisches Modul (kompiliert zu einer solchen Datei). Der Code ist gut kommentiert, um zu folgen.

Venki
quelle
1

Nur um mit allen Antworten fortzufahren, die hier gegeben wurden, insbesondere @James Lanes

Die Größe des Integer-Typs kann durch folgende Formel ausgedrückt werden:

Gesamtbereich = (2 ^ Bit-System)

untere Grenze = - (2 ^ Bit-System) * 0,5 obere Grenze = ((2 ^ Bit-System) * 0,5) - 1

Nader Belal
quelle
0

Es verwaltet sie, weil intund longGeschwister Klassendefinitionen sind. Sie haben geeignete Methoden für +, -, *, / usw., die Ergebnisse der entsprechenden Klasse liefern.

Beispielsweise

>>> a=1<<30
>>> type(a)
<type 'int'>
>>> b=a*2
>>> type(b)
<type 'long'>

In diesem Fall verfügt die Klasse intüber eine __mul__Methode (die * implementiert), die longbei Bedarf ein Ergebnis erstellt .

S.Lott
quelle