Python quản lý int và long như thế nào?


118

Có ai biết cách Python quản lý nội bộ kiểu int và long không?

  • Nó có chọn đúng loại động không?
  • Giới hạn cho một int là gì?
  • Tôi đang sử dụng Python 2.6, Có gì khác với các phiên bản trước không?

Tôi nên hiểu mã dưới đây như thế nào?

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

Cập nhật:

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

Họ không chỉ lập bản đồ các loại stdc nhanh chóng trong CPython?
Aiden Bell

Vâng, tôi nghĩ là họ làm. Tôi cũng nghi ngờ rằng mọi thứ được phân bổ trên heap, vì vậy khi một số cần độ chính xác hơn, chúng reallocsẽ ổn thôi. Nhưng tôi không chắc lắm, nên tôi sẽ để câu trả lời cho người khác.
zneak

2
Bạn cũng có thể buộc python để sử dụng biến dài vớivar = 666L
qba

8
@Ignacio: SAI Một CPython intlà chữ C long(mặc định là có chữ ký) ... xem <CPython 2.X source>/Include/intobject.h: typedef struct {PyObject_HEAD long ob_ival; } PyIntObject; Trong mọi trường hợp, Python 2.x intcho phép các số âm; một C unsignedsẽ không đối phó.
John Machin

PEP 237 thảo luận về cách mà Python được dùng để làm cho tất cả điều này dường như hoàn toàn giống nhau.
Carel

Câu trả lời:


124

intlongđã được "thống nhất" một vài phiên bản trở lại . Trước đó, có thể làm tràn một int thông qua các hoạt động toán học.

3.x đã nâng cao hơn nữa điều này bằng cách loại bỏ hoàn toàn dài và chỉ có int.

  • Python 2 : sys.maxintchứa giá trị lớn nhất mà một int Python có thể giữ.
    • Trên Python 2.7 64-bit, kích thước là 24 byte. Kiểm tra với sys.getsizeof().
  • Python 3 : sys.maxsizechứa kích thước tối đa tính bằng byte mà một int Python có thể có.
    • Đây sẽ là gigabyte ở 32 bit và exabyte ở 64 bit.
    • Một int lớn như vậy sẽ có giá trị tương tự như 8 với lũy thừa của sys.maxsize.

30
Nhưng Python3 gọi kiểu này là 'int', mặc dù nó hoạt động giống như 'long' của 2.x.

3
Bình luận của Ted: Như đã đề cập dưới đây hãy cẩn thận mà đúc một cái gì đó để int có nghĩa là lớn hơn maxint vẫn sẽ dẫn đến một >>> loại dài (int (sys.maxint + 1)) <type 'dài'>
StuartLC

2
sys.maxint sẽ cung cấp cho bạn số nguyên 64bit lớn nhất (trên máy 64bit của tôi). Một Long có thể lớn hơn nhiều 64bit, chỉ cần thử "sys.maxint << 1000000"
fccoelho Ngày

4
Trong python3, nó là sys.maxsize
pylover

3
sys.maxsize không liên quan gì đến số nguyên. Sys.maxint của Python 3 đã bị loại bỏ vì không có kích thước tối đa cho một số nguyên (Python 3 intgiống với Python 2 long).
asmeurer

19

PEP này sẽ hữu ích.

Điểm mấu chốt là bạn thực sự không cần phải lo lắng về điều đó trong các phiên bản python> 2.4


15
Bạn phải lo lắng về nó nếu bạn phải gọi một hàm int trong c với một cái gì đó không phù hợp với int (tức là một dài). Không có số lượng truyền long-> int sẽ giúp ích. Mới xảy ra với tôi.
Macke

1
@Macke: Nhận xét này đã cứu tôi, tôi cho rằng int sẽ thực hiện thủ thuật và tự hỏi tại sao tôi vẫn nhận được một ngoại lệ Jython.
ted

@Macke Hoàn toàn đúng. Tại công ty tôi đang làm việc, chúng tôi có một Trình mô phỏng được viết bằng Python, lấy dữ liệu đầu vào của người dùng thông qua các mục Tkinter và gửi các giá trị được đúc qua TCP / IP đến một máy khách (được viết bằng C / C ++) bắt chước một hệ thống nhúng. Hãy tưởng tượng những gì sẽ xảy ra khi bạn chèn 100000000000000000000000 trong bạn Python dựa trên nhập cảnh ...: P
rbaleksandar

@Mackie tốt nếu bạn thực sự bận tâm khi đọc PEP, nó nói rõ ràng: API C vẫn không thay đổi; Mã C sẽ vẫn cần phải biết về sự khác biệt giữa int ngắn và dài. (API Python 3.0 C có thể sẽ hoàn toàn không tương thích.) Các API PyArg_Parse * () đã chấp nhận các int dài, miễn là chúng nằm trong phạm vi có thể biểu diễn bằng C int hoặc long, vì vậy các hàm lấy C int hoặc long đối số sẽ thắng ' không phải lo lắng về việc đối phó với Python lâu.
cowbert

4

Trên máy của tôi:

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

Python sử dụng int (số nguyên có dấu 32 bit, tôi không biết chúng có phải là int C dưới mui xe hay không) cho các giá trị phù hợp với 32 bit, nhưng tự động chuyển sang longs (số lượng bit lớn tùy ý - tức là bignums) cho bất kỳ thứ gì lớn hơn. Tôi đoán rằng điều này sẽ tăng tốc mọi thứ cho các giá trị nhỏ hơn trong khi tránh bất kỳ sự cố tràn nào với quá trình chuyển đổi liền mạch sang bignums.


4

Hấp dẫn. Trên hộp 64-bit (i7 Ubuntu) của tôi:

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

Đoán nó bước lên tới 64 bit int trên một máy lớn hơn.


2
Python sử dụng kiểu số nguyên lớn hơn có sẵn cho máy. VẬY thường trên máy 32-bit int sẽ có kích thước 32 bit, trong khi trên máy 64 bit sẽ có kích thước 64 bit. Nhưng có thể có kiến ​​trúc 32 bit xác định số nguyên 64 bit, trong trường hợp đó python sẽ sử dụng số nguyên 64 bit.
Bakuriu

4

Python 2.7.9 tự động thúc đẩy các con số. Đối với trường hợp không chắc chắn sử dụng int () hoặc long ().

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

4

Python 2 sẽ tự động đặt kiểu dựa trên kích thước của giá trị. Bạn có thể tìm thấy hướng dẫn về giá trị tối đa bên dưới.

Giá trị tối đa của Int mặc định trong Python 2 là 65535, bất kỳ giá trị nào ở trên sẽ dài

Ví dụ:

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

Trong Python 3, kiểu dữ liệu dài đã bị loại bỏ và tất cả các giá trị số nguyên được xử lý bởi lớp Int. Kích thước mặc định của Int sẽ phụ thuộc vào kiến ​​trúc CPU của bạn.

Ví dụ:

  • Hệ thống 32 bit kiểu dữ liệu mặc định cho số nguyên sẽ là 'Int32'
  • Hệ thống 64 bit kiểu dữ liệu mặc định cho số nguyên sẽ là 'Int64'

Giá trị tối thiểu / tối đa của mỗi loại có thể được tìm thấy bên dưới:

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

Nếu kích thước Int của bạn vượt quá giới hạn đã đề cập ở trên, python sẽ tự động thay đổi loại của nó và phân bổ thêm bộ nhớ để xử lý sự gia tăng giá trị tối thiểu / tối đa này. Trong Python 2, nó sẽ chuyển đổi thành 'long', bây giờ nó chỉ chuyển đổi thành kích thước tiếp theo của Int.

Ví dụ: Nếu bạn đang sử dụng hệ điều hành 32 bit, giá trị tối đa của Int sẽ là 2147483647 theo mặc định. Nếu giá trị từ 2147483648 trở lên được chỉ định, loại sẽ được thay đổi thành Int64.

Có nhiều cách khác nhau để kiểm tra kích thước của int và cấp phát bộ nhớ của nó. Lưu ý: Trong Python 3, sử dụng phương thức type () tích hợp sẽ luôn trả về <class 'int'>bất kể kích thước Int bạn đang sử dụng.


1

Từ python 3.x, các ký tự số nguyên hợp nhất thậm chí còn thông minh hơn các phiên bản cũ. Trên hộp (i7 Ubuntu) của tôi, tôi nhận được thông tin sau,

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

Để biết chi tiết triển khai, hãy tham khảo Include/longintrepr.h, Objects/longobject.c and Modules/mathmodule.ctệp. Tệp cuối cùng là một mô-đun động (được biên dịch thành một tệp như vậy). Mã được bình luận tốt để làm theo.


1

Chỉ để tiếp tục tất cả các câu trả lời được đưa ra ở đây, đặc biệt là @James Làn đường

kích thước của kiểu số nguyên có thể được biểu thị bằng công thức sau:

tổng phạm vi = (hệ thống 2 ^ bit)

giới hạn dưới = - (hệ thống 2 ^ bit) * 0,5 giới hạn trên = ((hệ thống 2 ^ bit) * 0,5) - 1


0

Nó quản lý chúng bởi vì intlonglà các định nghĩa lớp anh em. Chúng có các phương thức thích hợp cho +, -, *, /, v.v., sẽ tạo ra kết quả của lớp thích hợp.

Ví dụ

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

Trong trường hợp này, lớp intcó một __mul__phương thức (phương thức thực thi *) tạo ra một longkết quả khi được yêu cầu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.