Jak Python radzi sobie z długimi i średnimi terminami?

118

Czy ktoś wie, jak Python zarządza wewnętrznie typami int i long?

  • Czy dynamicznie wybiera właściwy typ?
  • Jaki jest limit int?
  • Używam Pythona 2.6, czy różni się od poprzednich wersji?

Jak mam zrozumieć poniższy kod?

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

Aktualizacja:

>>> print type(0x7fffffff)
<type 'int'>
>>> print type(0x80000000)
<type 'long'>
luc
źródło
Czy nie odwzorowują one po prostu na bieżąco typów standardowych w CPythonie?
Aiden Bell
Tak, myślę, że tak. Podejrzewam również, że wszystko jest przydzielone na stosie, więc gdy liczba wymaga większej precyzji, po prostu reallocwszystko w porządku. Ale nie jestem do końca pewien, więc odpowiedź zostawię komuś innemu.
zneak
2
Możesz także zmusić Pythona do używania długich zmiennych z var = 666L
opcją
8
@Ignacio: ŹLE CPython intjest C long(domyślnie jest podpisany) ... zobacz <CPython 2.X source>/Include/intobject.h: typedef struct {PyObject_HEAD długo ob_ival; } PyIntObject; W każdym razie Python 2.x intdopuszcza liczby ujemne; C unsignedpo prostu by sobie nie poradził.
John Machin,
PEP 237 omawia, jak pod maską Python ma sprawić, że wszystko będzie pozornie takie samo.
Carel,

Odpowiedzi:

124

inti longzostały „ujednolicone” kilka wersji wstecz . Wcześniej możliwe było przepełnienie int przez operacje matematyczne.

3.x jeszcze bardziej to rozwinął, całkowicie eliminując long i mając tylko int.

  • Python 2 : sys.maxintzawiera maksymalną wartość, jaką może przechowywać Python int.
    • W 64-bitowym Pythonie 2.7 rozmiar wynosi 24 bajty. Sprawdź z sys.getsizeof().
  • Python 3 : sys.maxsizezawiera maksymalny rozmiar w bajtach, jaki może mieć wartość int w Pythonie.
    • Będą to gigabajty na 32 bitach i eksabajty na 64 bitach.
    • Tak duża liczba int miałaby wartość zbliżoną do 8 do potęgi sys.maxsize.
Ignacio Vazquez-Abrams
źródło
30
Ale Python3 nazywa ten typ „int”, mimo że zachowuje się bardziej jak „long” 2.x.
3
Komentarz Teda: Jak wspomniano poniżej, uważaj, że rzutowanie czegoś do int, które jest większe niż maxint, nadal będzie skutkować długim >>> typem (int (sys.maxint + 1)) <type 'long'>
StuartLC
2
sys.maxint da największą 64-bitową liczbę całkowitą (na mojej 64-bitowej maszynie) a Long może być znacznie większy niż 64-bitowy, po prostu spróbuj "sys.maxint << 1000000"
fccoelho
4
W pythonie3 jest to sys.maxsize
pylover
3
sys.maxsize nie ma nic wspólnego z liczbami całkowitymi. Python 3 sys.maxint został usunięty, ponieważ nie ma maksymalnego rozmiaru dla liczby całkowitej (Python 3 intjest taki sam jak Python 2 long).
asmeurer
19

Ten PEP powinien pomóc.

Najważniejsze jest to, że naprawdę nie powinieneś się tym martwić w wersjach Pythona> 2.4

mluebke
źródło
15
Musisz się tym martwić, jeśli musisz wywołać funkcję int w c z czymś, co nie mieści się w int (tj. Long). Żadna ilość rzutów long-> int nie pomoże. Przydarzyło mi się to niedawno.
Macke,
1
@Macke: Ten komentarz uratował mnie, założyłem, że int załatwi sprawę i zastanawiałem się, dlaczego wciąż otrzymuję wyjątek Jythona.
ted
@Macke Absolutnie prawdziwe. W firmie, w której obecnie pracuję, mamy symulator napisany w Pythonie, który przyjmuje dane wejściowe użytkownika przez wpisy Tkintera i wysyła wyrzucone wartości przez TCP / IP do klienta (napisanego w C / C ++), który naśladuje system osadzony. Wyobraź sobie, co się stanie, gdy wstawisz 100000000000000000000000 do wpisu opartego na Pythonie ...: P
rbaleksandar
@Mackie cóż, jeśli faktycznie zadałeś sobie trud przeczytania PEP, wyraźnie mówi: C API pozostaje niezmienione; Kod C nadal będzie musiał być świadomy różnicy między krótkimi i długimi liczbami int. (API Pythona 3.0 C prawdopodobnie będzie całkowicie niekompatybilne.) API PyArg_Parse * () już akceptują długie int, o ile mieszczą się w zakresie reprezentowanym przez C ints lub longs, tak aby wygrywały funkcje przyjmujące C int lub long argument ' Nie muszę się martwić o radzenie sobie z tęsknotą w Pythonie.
cowbert
4

Na moim komputerze:

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

Python używa liczb całkowitych (32-bitowe liczby całkowite ze znakiem, nie wiem, czy pod maską są to liczby całkowite C, czy nie) dla wartości pasujących do 32-bitowych, ale automatycznie przełącza się na długie (dowolnie dużą liczbę bitów - tj. Bignum) na wszystko większy. Domyślam się, że przyspiesza to działanie dla mniejszych wartości, unikając jednocześnie przepełnień z płynnym przejściem na bignum.

MAK
źródło
4

Ciekawy. Na moim 64-bitowym (i7 Ubuntu) pudełku:

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

Chyba zwiększa się do 64-bitowych intów na większej maszynie.

Gringo Suave
źródło
2
Python używa większego typu liczby całkowitej dostępnej dla maszyny. SO zwykle na maszynach 32-bitowych int będzie miał rozmiar 32-bitowy, podczas gdy na maszynach 64-bitowych będzie miał rozmiar 64-bitowy. Ale mogą istnieć architektury 32-bitowe definiujące 64-bitowe liczby całkowite, w takim przypadku Python użyłby 64-bitowej liczby całkowitej.
Bakuriu,
4

Python 2.7.9 automatycznie promuje liczby. W przypadku, gdy nie ma pewności co do użycia int () lub long ().

>>> a = int("123")
>>> type(a)
<type 'int'>
>>> a = int("111111111111111111111111111111111111111111111111111")
>>> type(a)
<type 'long'>
nvd
źródło
4

Python 2 automatycznie ustawi typ na podstawie rozmiaru wartości. Przewodnik po maksymalnych wartościach można znaleźć poniżej.

Wartość Max domyślnej wartości Int w Pythonie 2 to 65535, wszystko powyżej będzie długie

Na przykład:

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

W Pythonie 3 długi typ danych został usunięty, a wszystkie wartości całkowite są obsługiwane przez klasę Int. Domyślny rozmiar Int będzie zależał od architektury procesora.

Na przykład:

  • W systemach 32-bitowych domyślnym typem danych dla liczb całkowitych będzie „Int32”
  • Systemy 64-bitowe domyślnym typem danych dla liczb całkowitych będzie „Int64”

Wartości min / max każdego typu można znaleźć poniżej:

  • 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]

Jeśli rozmiar twojego Int przekracza limity wymienione powyżej, Python automatycznie zmieni jego typ i przydzieli więcej pamięci, aby obsłużyć ten wzrost wartości min / max. Podczas gdy w Pythonie 2 konwertowałoby się to na „długie”, teraz po prostu konwertuje się na następny rozmiar Int.

Przykład: jeśli używasz 32-bitowego systemu operacyjnego, maksymalna wartość Int będzie domyślnie wynosiła 2147483647. Jeśli przypisana zostanie wartość 2147483648 lub więcej, typ zostanie zmieniony na Int64.

Istnieją różne sposoby sprawdzenia rozmiaru int i alokacji pamięci. Uwaga: W Pythonie 3 użycie wbudowanej metody type () zawsze zwróci <class 'int'>bez względu na używany rozmiar Int.

James Lane
źródło
1

Począwszy od Pythona 3.x, zunifikowane biblioteki liczb całkowitych są jeszcze inteligentniejsze niż starsze wersje. Na moim (i7 Ubuntu) pudełku otrzymałem następujące informacje,

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

Szczegóły implementacji znajdują się w Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.cplikach. Ostatni plik jest modułem dynamicznym (skompilowanym do pliku so). Kod jest dobrze skomentowany.

Venki
źródło
1

Aby przejść do wszystkich udzielonych tutaj odpowiedzi, zwłaszcza @James Lanes

wielkość typu całkowitego można wyrazić następującym wzorem:

całkowity zakres = (system 2 ^ bitowy)

dolna granica = - (system 2 ^ bitowy) * 0,5 górna granica = ((system 2 ^ bitowy) * 0,5) - 1

Nader Belal
źródło
0

Zarządza nimi, bo inti longsą rodzeństwem definicje klas. Mają odpowiednie metody na +, -, *, / itd., Które dadzą wyniki odpowiedniej klasy.

Na przykład

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

W tym przypadku klasa intma __mul__metodę (tę, która implementuje *), która w longrazie potrzeby tworzy wynik.

S.Lott
źródło