2014-09-18 326 views
0

我試圖在Cython類中將大負值轉換爲uint64_t類型變量。但我不斷收到此錯誤:Cython無法將負值轉換爲無符號long

OverflowError:不能負的值轉換爲unsigned long

cdef uint64_t temp2 = <uint64_t>(temp - bitReversal(current_pos)) 

我從temp - bitReversal(current_pos)得到的數字是-1152831344652320768,如果我硬編碼它的工作原理。現在我構建了一個非常醜陋的黑客將負數轉換爲相應的未簽名數字,但它的速度真的很慢。

+0

將''更改爲'(uint64_t)'? (並接受溢出。) – user2864740 2014-09-18 23:11:56

+0

我可以問*爲什麼*您試圖將負數轉換爲無符號值? – CoryKramer 2014-09-18 23:12:03

+0

我正在計算與棋類似的遊戲的移動掩碼。「(uint64_t)'不是cython的有效語法 – 2014-09-18 23:16:20

回答

1

感謝abarnert工作。 這行使它的工作: cdef uint64_t temp2 = <uint64_t>(temp - <uint64_t>bitReversal(current_pos))

但它真的很奇怪,因爲這兩個變量的類型uint64_t。

def bitReversal(uint64_t x): 
    x = (((x & 0xaaaaaaaaaaaaaaaa) >> 1) | ((x & 0x5555555555555555) << 1)) 
    x = (((x & 0xcccccccccccccccc) >> 2) | ((x & 0x3333333333333333) << 2)) 
    x = (((x & 0xf0f0f0f0f0f0f0f0) >> 4) | ((x & 0x0f0f0f0f0f0f0f0f) << 4)) 
    x = (((x & 0xff00ff00ff00ff00) >> 8) | ((x & 0x00ff00ff00ff00ff) << 8)) 
    x = (((x & 0xffff0000ffff0000) >> 16) | ((x & 0x0000ffff0000ffff) << 16)) 
    cdef uint64_t result = <uint64_t>((x >> 32) | (x << 32)) 
    return result 
+2

兩個變量都不能是'uint64_t',或者減法不會出現負值。你可能在某處丟失了一個'cdef',所以其中一個變量被複制到了一個Python'int'的某處?在那種情況下,我相信Cython會通過將C值轉換爲Python並要求Python減去(除了這個溢出問題,也可能恰好是您希望避免的性能問題),從而減去它們。 – abarnert 2014-09-18 23:52:26

+0

使用'cython -a myfile.pyx'並尋找黃色。如果你的數學是黃色的,abarnert是在錢上。 – Veedrac 2014-09-20 11:35:32