如何在Python中进行C语言计算

时间:2011-06-16 00:52:24

标签: python numpy ctypes

我想在Python中进行一些C语言计算模拟。 例如,unsigned short,single precision float ...

ushort(0xffff) + 1 -> 0
0.1f * 0.1f -> ...

是否有一些库可以在Python中执行此操作?

我可以使用ctypes来创建unsigned short,single float,但是它们 不能做数学运算:

a = c_uint16(0xffff)
b = c_uint16(0x01)
a+b -> TypeError

或者,我可以使用numpy:

>>> np.uint16(0xffff) + np.uint16(0x01)
Warning: overflow encountered in ushort_scalars
0

但与Python的正常计算相比,它非常慢:

>>> timeit.timeit("a+b", "import numpy as np;a=np.uint16(0xfffe);b=np.uint16(0x01)")
0.35577465681618037
>>> timeit.timeit("0xfffe+0x01")
0.022638104432360251
>>> timeit.timeit("np.uint16(0xfffe) + np.uint16(0x01)", "import numpy as np")
5.904765399236851  

编辑:

>>> timeit.timeit("a+b", "a=0xfffe;b=0x01")
0.040062221014295574  

2 个答案:

答案 0 :(得分:6)

编译0xfffe+0x01时,会将其折叠为常量65535。你没有计算加法所需的时间 - 你只是测量加载常数的时间:

>>> dis.dis(compile("0xfffe+0x01", "", "eval"))
  1           0 LOAD_CONST               2 (65535)
              3 RETURN_VALUE        

添加NumPy标量比添加内置整数要慢,但它不会比纯Python更好。考虑使用Cython - 它将允许您声明类型并以C速度执行计算。或者,尝试在NumPy中矢量化代码(也就是说,如果速度真的很重要)。

答案 1 :(得分:1)

您可以使用模%2**sizeof(在您的情况下,2 ** 16或65536)为每个操作创建一个函数

def add(a, b, mod=2**16):
    return (a+b) % mod

def sub(a, b, mod=2**16):
    return (a-b) % mod

以及您需要的任何其他功能。

>>> add(0xffff, 1)
0
>>> sub(10, 20)
65526

请注意,这仅适用于无符号类型。对于已签名的,您可以使用用于修改的值的一半(即2 ** 15),并且必须在应用模数之前验证结果