Bagaimana Python mengatur int dan long?


118

Apakah ada yang tahu bagaimana Python mengelola tipe int dan long secara internal?

  • Apakah ia memilih jenis yang tepat secara dinamis?
  • Berapa batas int?
  • Saya menggunakan Python 2.6, Apakah berbeda dengan versi sebelumnya?

Bagaimana saya harus memahami kode di bawah ini?

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

Memperbarui:

>>> print type(0x7fffffff)
<type 'int'>
>>> print type(0x80000000)
<type 'long'>

Bukankah mereka hanya memetakan ke tipe stdc dengan cepat, underneat di CPython?
Aiden Bell

Ya, saya pikir mereka melakukannya. Saya juga menduga bahwa semuanya dialokasikan di heap, jadi ketika suatu angka membutuhkan ketelitian lebih, mereka baik-baik saja realloc. Tapi saya tidak begitu yakin, jadi saya akan menyerahkan jawabannya kepada orang lain.
zneak

2
Anda juga dapat memaksa python untuk menggunakan variabel panjang denganvar = 666L
qba

8
@Ignacio: SALAH CPython intadalah C long(default ditandatangani) ... lihat <CPython 2.X source>/Include/intobject.h: typedef struct {PyObject_HEAD long ob_ival; } PyIntObject; Bagaimanapun, Python 2.x intmengizinkan bilangan negatif; a C unsignedtidak akan mengatasinya.
John Machin

PEP 237 membahas bagaimana Python dimaksudkan untuk membuat semua ini tampak sama.
Carel

Jawaban:


124

intdan long"disatukan" beberapa versi sebelumnya . Sebelumnya itu mungkin untuk melimpah int melalui operasi matematika.

3.x telah memajukan lebih jauh ini dengan menghilangkan long sama sekali dan hanya memiliki int.

  • Python 2 : sys.maxintberisi nilai maksimum yang dapat ditampung oleh int Python.
    • Pada Python 2.7 64-bit, ukurannya 24 byte. Periksa dengan sys.getsizeof().
  • Python 3 : sys.maxsizeberisi ukuran maksimum dalam byte yang bisa dimiliki oleh int Python.
    • Ini akan menjadi gigabyte dalam 32 bit, dan exabyte dalam 64 bit.
    • Int sebesar itu akan memiliki nilai yang mirip dengan 8 pangkat sys.maxsize.

30
Tapi Python3 menyebut tipe ini 'int', meskipun berperilaku lebih seperti 2.x's 'long'.

3
Komentar oleh Ted: Seperti yang disebutkan di bawah ini, berhati-hatilah karena mentransmisikan sesuatu ke int yang lebih besar dari maxint akan tetap menghasilkan tipe >>> yang panjang (int (sys.maxint + 1)) <type 'long'>
StuartLC

2
sys.maxint akan memberi Anda integer 64bit terbesar (pada mesin 64bit saya) a Long bisa jauh lebih besar dari 64bits, coba saja "sys.maxint << 1000000"
fccoelho

4
Di python3 itu adalah sys.maxsize
pylover

3
sys.maxsize tidak ada hubungannya dengan integer. Sys.maxint Python 3 telah dihapus karena tidak ada ukuran maksimum untuk sebuah integer (Python 3 intsama dengan Python 2 long).
asmeurer

19

PEP ini akan membantu.

Intinya adalah Anda tidak perlu khawatir tentang itu di versi python> 2.4


15
Anda harus mengkhawatirkannya jika Anda harus memanggil fungsi int di c dengan sesuatu yang tidak muat di int (yaitu a long). Tidak ada jumlah casting long-> int yang akan membantu. Terjadi pada saya baru-baru ini.
Macke

1
@Macke: Komentar ini menyelamatkan saya, saya berasumsi bahwa int akan melakukan trik, dan bertanya-tanya mengapa saya masih mendapatkan pengecualian Jython.
ted

@E Benar sekali. Di perusahaan tempat saya bekerja saat ini kami memiliki Simulator yang ditulis dengan Python yang mengambil input pengguna melalui entri Tkinter dan mengirimkan nilai yang dicor melalui TCP / IP ke klien (ditulis dalam C / C ++) yang meniru sistem tertanam. Bayangkan apa yang terjadi ketika Anda memasukkan 100000000000000000000000 di Entri berbasis Python Anda ...: P
rbaleksandar

@Mackie baik jika Anda benar-benar repot untuk membaca PEP, secara eksplisit mengatakan: C API tetap tidak berubah; Kode C masih perlu memperhatikan perbedaan antara int pendek dan panjang. (Python 3.0 C API mungkin akan sepenuhnya tidak kompatibel.) PyArg_Parse * () API sudah menerima int yang panjang, selama mereka berada dalam kisaran yang dapat direpresentasikan oleh C int atau long, sehingga fungsi yang menggunakan C int atau argumen panjang menang ' Anda tidak perlu khawatir berurusan dengan rindu Python.
cowbert

4

Di mesin saya:

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

Python menggunakan ints (bilangan bulat bertanda 32 bit, saya tidak tahu apakah itu C int atau tidak) untuk nilai yang sesuai dengan 32 bit, tetapi secara otomatis beralih ke long (sejumlah besar bit sewenang-wenang - yaitu bignum) untuk apa pun lebih besar. Saya menduga ini mempercepat segalanya untuk nilai yang lebih kecil sambil menghindari luapan apa pun dengan transisi mulus ke bignum.


4

Menarik. Di kotak 64-bit (i7 Ubuntu) saya:

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

Tebak itu melangkah hingga 64 bit int pada mesin yang lebih besar.


2
Python menggunakan tipe integer yang lebih besar yang tersedia untuk mesin. SO biasanya pada mesin 32-bit int akan berukuran 32bit, sedangkan pada mesin 64 bit akan memiliki ukuran 64 bit. Tetapi mungkin ada arsitektur 32-bit yang mendefinisikan integer 64 bit, dalam hal ini python akan menggunakan integer 64-bit.
Bakuriu

4

Python 2.7.9 mempromosikan angka secara otomatis. Untuk kasus di mana seseorang tidak yakin untuk menggunakan int () atau long ().

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

4

Python 2 secara otomatis akan mengatur jenis berdasarkan ukuran nilainya. Panduan nilai maks dapat ditemukan di bawah.

Nilai Max dari Int default di Python 2 adalah 65535, apapun di atasnya akan menjadi panjang

Sebagai contoh:

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

Dalam Python 3, tipe data panjang telah dihapus dan semua nilai integer ditangani oleh kelas Int. Ukuran default Int akan bergantung pada arsitektur CPU Anda.

Sebagai contoh:

  • Sistem 32 bit, tipe data default untuk integer adalah 'Int32'
  • Sistem 64 bit, tipe data default untuk integer adalah 'Int64'

Nilai min / max dari setiap jenis dapat ditemukan di bawah ini:

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

Jika ukuran Int Anda melebihi batas yang disebutkan di atas, python akan secara otomatis mengubah jenisnya dan mengalokasikan lebih banyak memori untuk menangani peningkatan nilai min / max ini. Di Python 2, itu akan diubah menjadi 'panjang', sekarang hanya diubah menjadi ukuran Int berikutnya.

Contoh: Jika Anda menggunakan sistem operasi 32 bit, nilai maksimal Int Anda adalah 2147483647 secara default. Jika nilai 2147483648 atau lebih ditetapkan, tipe akan diubah menjadi Int64.

Ada berbagai cara untuk memeriksa ukuran int dan alokasi memorinya. Catatan: Dalam Python 3, menggunakan metode built-in type () akan selalu mengembalikan <class 'int'>berapa pun ukuran Int yang Anda gunakan.


1

Dari python 3.x, libries integer terpadu bahkan lebih pintar dari versi sebelumnya. Di kotak (i7 Ubuntu) saya, saya mendapatkan yang berikut ini,

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

Untuk detail implementasi, lihat Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.cfile. File terakhir adalah modul dinamis (dikompilasi menjadi file jadi). Kode ini dikomentari dengan baik untuk diikuti.


1

Sekadar melanjutkan semua jawaban yang diberikan di sini, terutama @James Lanes

ukuran tipe integer dapat diekspresikan dengan rumus ini:

kisaran total = (2 ^ sistem bit)

batas bawah = - (2 ^ sistem bit) * 0,5 batas atas = ((2 ^ sistem bit) * 0,5) - 1


0

Itu mengaturnya karena intdan longmerupakan definisi kelas saudara. Mereka memiliki metode yang sesuai untuk +, -, *, /, dll., Yang akan menghasilkan hasil dari kelas yang sesuai.

Sebagai contoh

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

Dalam hal ini, kelas intmemiliki __mul__metode (yang mengimplementasikan *) yang membuat longhasil saat diperlukan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.