2014-09-18 334 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