簡體   English   中英

OverflowError:Python int太大,無法在for循環中轉換為C

[英]OverflowError: Python int too large to convert to C long in a for loop

我正在使用cython遍歷大量數字,這就是test.pyx

cpdef int counter(int n):
    cdef int count= 0
    cdef int i
    for i in range(n):
        count += i*2
    return count

跑步

>>> counter(10000000000)

給出以下錯誤:

OverflowError:Python int太大,無法轉換為C long

我沒有使用numpy或任何其他庫,只是一個簡單的for循環。 有可能解決這個問題嗎?

簡短的回答:是的,您可以修復它,使用c類型的“ long long”,而不是c類型的“ int”。

錯誤的長答案和解釋:

cython中的參數是ac int(不要與python 2 int或python 3 int有所不同),它們的范圍是有限的。 假設現代台式機/服務器的操作系統范圍幾乎可以確定為−2147483648至2147483647。 因此顯然10000000000將不適合。 我們這里有一個錯誤,但是當您使用int類型時,為什么錯誤消息中提到“ long”? 讓我們嘗試看一下代碼。

查看cython生成的源,此轉換。 由函數“ __Pyx_PyInt_As_int”處理。 通過將C類型名稱替換為文本模板可以清楚地創建此函數,其結果是其中包含大量的無效代碼。 讓我們努力吧。

static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) {
   const int neg_one = (int) -1, const_zero = (int) 0;
   const int is_unsigned = neg_one > const_zero;

第一部分代碼指出函數正在使用的C類型是否為無符號。

#if PY_MAJOR_VERSION < 3
     <----- snip---->
#endif

這段代碼對我們而言並不重要,它僅在python對象為python 2.x int時才有效(不要與C int或python 3.x int混淆)。

    if (likely(PyLong_Check(x))) {

現在我們到達某個地方,這就是處理python2 long和python3 ints的情況

        if (is_unsigned) {
            <---snip a massive chunk of dead code---> 
        } else {
#if CYTHON_USE_PYLONG_INTERNALS
             <--snip a bunch of optimisations for easy cases-->
#endif
        if (sizeof(int) <= sizeof(long)) {
            __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x))

最后,我們對您的錯誤消息進行了解釋。 如果“簡易情況”代碼無法處理該值,則首先將其從python3 int / python2 long轉換為C long。 然后,將C long轉換為C int。 因此,在具有32位長的平台上,在嘗試將10000000000轉換為long之前,轉換嘗試將其轉換為int失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM