2011-01-20 39 views
13

我想使用我在網上找到的算法生成兩個非常大的素數。Python OverflowError:無法將「long」放入index =大小的整數

我得到這個錯誤在第5行:

Python OverflowError: cannot fit 'long' into an index=sized integer 

我的代碼:

import math 
def atkin(end): 
    if end < 2: return [] 
    lng = ((end/2)-1+end%2) 
    **sieve = [True]*(lng+1)** 
    for i in range(int(math.sqrt(end)) >> 1): 
     if not sieve[i]: continue 
     for j in range((i*(i + 3) << 1) + 3, lng, (i << 1) + 3): 
      sieve[j] = False 
    primes = [2] 
    primes.extend([(i << 1) + 3 for i in range(lng) if sieve[i]]) 
    return primes 

我怎樣才能解決我的錯誤?

如果你知道更好的方法來產生大質數,那也是有幫助的。

+1

你是否試過這個小數字的代碼?如果你想使用大數字,你應該嘗試http://gmplib.org/ library。這個庫有一個Python包裝器,它對我來說工作得很好。 – Elalfer 2011-01-20 19:46:39

回答

11

下面的代碼表明您正在運行到這個問題:

import sys 
x = [True]*(sys.maxint+1) 

其產生的OverflowError。如果你改爲:

x = [True]*(sys.maxint) 

那麼你應該得到一個MemoryError

這是怎麼回事。 Python可以使用自己的可擴展數據類型來處理任意大的整數。但是,當您嘗試創建如上所述的列表時,Python會嘗試將小列表重複的次數(Python整數)轉換爲Py_ssize_t類型的C整數。 Py_ssize_t根據您的構建而定義不同,但可以是ssize_t,long或int。本質上,Python在進行轉換之前檢查Python整數是否適合C整數類型,如果它不起作用則引發OverflowError。

1

第5行trues分配一個完整的True值的長列表。可能你的lng太大,不適合內存中的列表?

我無法完全重現您的錯誤;在最壞的情況下,我最終只用了MemoryError

也許算法是可以的(儘管我不能打賭),只是嘗試一個較小的數字。