Xử lý số lượng rất lớn trong Python


139

Tôi đã xem xét đánh giá tay bài nhanh trong Python. Tôi nhận ra rằng một cách để tăng tốc quá trình sẽ là đại diện cho tất cả các mặt thẻ và bộ quần áo dưới dạng số nguyên tố và nhân chúng lại với nhau để đại diện cho bàn tay. Để trắng:

class PokerCard:
    faces = '23456789TJQKA'
    suits = 'cdhs'
    facePrimes = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 53, 59, 61]
    suitPrimes = [2, 3, 5, 7]

    def HashVal(self):
      return PokerCard.facePrimes[self.cardFace] * PokerCard.suitPrimes[self.cardSuit]

Điều này sẽ cung cấp cho mỗi bàn tay một giá trị số mà thông qua modulo có thể cho tôi biết có bao nhiêu vị vua trong tay hoặc bao nhiêu trái tim. Ví dụ: bất kỳ tay nào có năm câu lạc bộ trở lên sẽ chia đều cho 2 ^ 5; bất kỳ tay nào có bốn vị vua sẽ chia đều cho 59 ^ 4, v.v.

Vấn đề là một tay bảy thẻ như AcAdAhAsKdKhKs có giá trị băm xấp xỉ 62,7 triệu, sẽ mất hơn 32 bit để thể hiện nội bộ. Có cách nào để lưu trữ số lượng lớn như vậy trong Python sẽ cho phép tôi thực hiện các phép toán số học trên nó không?


13
Bạn có chắc chắn rằng, một khi bạn bắt đầu đại diện cho dữ liệu của mình theo cách này, bạn sẽ vẫn thấy bất kỳ cải thiện tốc độ đáng kể nào không? Tôi nhận ra điều này không trả lời câu hỏi của bạn, nhưng vẫn ..
Thomi

3
Tôi có một đề xuất: thay vì sử dụng các biến riêng biệt cho các giá trị thẻ và biểu diễn, tôi đề nghị sử dụng từ điển. (Vì vậy, khuôn mặt = {'2': 11, '3': 13, '4': 17, '5': 19, '6': 23, '7': 29, '8': 31, '9' : 37, 'T': 41, 'J': 43, 'Q': 53, 'K': 59, 'A': 61} và bộ quần áo = {'c': 2, 'd': 3, ' h ': 5,' s ': 7}.)
JAB

Câu trả lời:


176

Python hỗ trợ kiểu số nguyên "bignum" có thể hoạt động với số lượng lớn tùy ý. Trong Python 2.5+, loại này được gọi longvà tách biệt với intloại, nhưng trình thông dịch sẽ tự động sử dụng loại nào phù hợp hơn. Trong Python 3.0+, intloại đã bị loại bỏ hoàn toàn.

Tuy nhiên, đó chỉ là một chi tiết triển khai - miễn là bạn có phiên bản 2.5 trở lên, chỉ cần thực hiện các phép toán tiêu chuẩn và bất kỳ số nào vượt quá ranh giới của toán học 32 bit sẽ được tự động (và trong suốt) được chuyển đổi thành một bignum.

Bạn có thể tìm thấy tất cả các thông tin chi tiết trong PEP 0237 .


2
Câu hỏi đặt ra là liệu hiệu suất đạt được từ việc sử dụng bignum thay vì số nguyên 32 bit có vượt quá lợi ích hiệu suất từ ​​phương pháp đánh giá tay thông minh mà anh ta đang sử dụng.
Chris Up nhẫn

3
Trên thực tế, rào cản giữa int và long đã bị phá vỡ trong 2.5. 3.0 loại bỏ int hoàn toàn, làm cho loại số nguyên duy nhất dài.
Ignacio Vazquez-Abrams

1
Làm thế nào lớn là một num lớn? Nó có thể là PHI ^ 4000000 không?
Mike Caron

9
@Mike Caron - Nếu cấu trúc được liệt kê trong PEP 0237 là chính xác, longđộ dài của s (tính bằng chữ số) được lưu dưới dạng số nguyên 32 bit không dấu, tối đa 4.294.967.295 chữ số, có nghĩa là chúng có thể dễ dàng giữ φ ** (4 * 10 ** 6 ), "chỉ" 832.951 chữ số. Tuy nhiên, không phải là số nguyên, vì vậy bạn sẽ cần sử dụng Số thập phân (dấu phẩy động của Python) để tính số. longTuy nhiên, bạn có thể lưu trữ kết quả sau đó.
Ben Trống

17
@ IgnacioVazquez-Abrams Chỉ là một điểm cần làm rõ, longlà loại số nguyên duy nhất trong 3.0, nhưng nó được đặt tên int. (Và cái cũ intđã biến mất.)
Michael Mior

70

python hỗ trợ số nguyên lớn tùy ý một cách tự nhiên:

thí dụ:

>>>10 ** 1000 100000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Bạn thậm chí có thể nhận được, ví dụ như một giá trị số nguyên rất lớn, 400 (4000000).

Nhưng nó vẫn không (hiện tại) hỗ trợ một số float lớn tùy ý !!

Nếu bạn cần một cái lớn, lớn, nổi, hãy kiểm tra Mô-đun thập phân. Có những ví dụ về việc sử dụng trên các forun này: OverflowError: (34, 'Kết quả quá lớn')

Một tài liệu tham khảo khác: http://docs.python.org/2/l Library / decimal.html

Bạn thậm chí có thể sử dụng mô-đun gmpy nếu bạn cần tăng tốc (có thể là mối quan tâm của bạn): Xử lý số lượng lớn trong mã

Một tài liệu tham khảo khác: https://code.google.com.vn/p/gmpy/


32

Bạn có thể làm điều này vì niềm vui của nó, nhưng khác hơn là nó không phải là một ý tưởng tốt. Nó sẽ không tăng tốc bất cứ điều gì tôi có thể nghĩ ra.

  • Lấy thẻ trong tay sẽ là một hoạt động bao thanh toán số nguyên tốn kém hơn nhiều so với việc chỉ truy cập vào một mảng.

  • Thêm thẻ sẽ là phép nhân và loại bỏ phân chia thẻ, cả hai số nhiều từ lớn, hoạt động tốn kém hơn so với việc thêm hoặc xóa các thành phần khỏi danh sách.

  • Giá trị số thực tế của một bàn tay sẽ không cho bạn biết gì. Bạn sẽ cần phải tính các số nguyên tố và tuân theo các quy tắc Poker để so sánh hai tay. h1 <h2 cho những bàn tay như vậy có nghĩa là gì.


25

python hỗ trợ số nguyên lớn tùy ý một cách tự nhiên:

In [1]: 59**3*61**4*2*3*5*7*3*5*7
Out[1]: 62702371781194950
In [2]: _ % 61**4
Out[2]: 0

3

Trình thông dịch python sẽ xử lý nó cho bạn, bạn chỉ cần thực hiện các thao tác của mình (+, -, *, /) và nó sẽ hoạt động như bình thường.

Các intgiá trị giới hạn.

Cẩn thận khi thực hiện phân chia, theo mặc định thương số được chuyển thành float, nhưng floatkhông hỗ trợ số lượng lớn như vậy. Nếu bạn nhận được thông báo lỗi floatkhông hỗ trợ số lượng lớn như vậy, thì điều đó có nghĩa là thương số quá lớn để được lưu trữ trong floatbạn sẽ phải sử dụng phép chia tầng ( //).

Nó bỏ qua bất kỳ số thập phân nào sau dấu thập phân, theo cách này, kết quả sẽ là int, do đó bạn có thể có một kết quả số lớn.

10//3 Đầu ra 3

10//4 đầu ra 2


1
Làm thế nào để câu trả lời của bạn giải quyết số lượng lớn vấn đề trong câu hỏi?
St nguWolf

Điều đó có nghĩa là bạn chỉ có thể thực hiện các thao tác bình thường với số lượng lớn nhưng hãy cẩn thận với việc phân chia
Hedy
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.