是否有可能,如果是的话,如何确定Cython中整数数据类型的大小(以位为单位)?
我正在尝试做这样的事情,以获得整数大小:
cdef WORD_BITS = 0
IF sizeof(unsigned long long) == 8:
WORD_BITS = 64
DEF VECTOR_LENGTH_SHIFT_AMOUNT = 6
ELSE:
WORD_BITS = 32
DEF VECTOR_LENGTH_SHIFT_AMOUNT = 5
ctypedef unsigned long long word_t
cdef int vector_length(size_t bit_size):
cdef size_t size = bit_size >> VECTOR_LENGTH_SHIFT_AMOUNT
if size << VECTOR_LENGTH_SHIFT_AMOUNT < bit_size:
size += 1
return size
cdef class BitVector(object):
cdef size_t length
cdef size_t array_size
cdef word_t *array
def __cinit__(self, size_t size):
self.length = size
self.array_size = vector_length(size)
self.array = <word_t *>calloc(self.array_size, sizeof(word_t))
def __dealloc__(self):
free(self.array)
Run Code Online (Sandbox Code Playgroud)
我需要处理数组元素的单个位和元素本身,因此我必须知道它们包含多少位(计算正确的掩码/移位).尝试编译上面的代码产生:
$python setup.py build_ext --inplace
Compiling bitvector.pyx because it changed.
Cythonizing bitvector.pyx
Error compiling Cython file:
------------------------------------------------------------
...
cimport cython
# check whether we are running on a 64 or 32 bit architecture.
cdef WORD_BITS = 0
IF sizeof(unsigned long long) == 8:
^
------------------------------------------------------------
bitvector.pyx:7:3: Invalid compile-time expression
Traceback (most recent call last):
File "setup.py", line 6, in <module>
ext_modules=cythonize('bitvector.pyx')
File "/usr/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 673, in cythonize
cythonize_one(*args[1:])
File "/usr/lib/python2.7/dist-packages/Cython/Build/Dependencies.py", line 737, in cythonize_one
raise CompileError(None, pyx_file)
Cython.Compiler.Errors.CompileError: bitvector.pyx
Run Code Online (Sandbox Code Playgroud)
有替代方案吗?
我知道有一个stdint.h标题应该定义整数类型,但我想不出一种方法来使用它,因为:
IF uint64_t is not defined:地用Cython?).DEF用IFs 来检查由编译器定义的东西,因此我怀疑我是否能够使用它stdint.h.看起来这在Cython中是不可行的,因为我想做的检查只能在从C编译到机器代码时执行,而不是从cython到C编译.
现在我想知道:是否有可能以这样的方式编写一个cython扩展,以便在C源代码中添加这种检查?
我的意思是,我能以某种方式写道:
cdef WORD_BITS = 0
IF sizeof(unsigned long long) == 8:
WORD_BITS = 64
DEF VECTOR_LENGTH_SHIFT_AMOUNT = 6
ELSE:
WORD_BITS = 32
DEF VECTOR_LENGTH_SHIFT_AMOUNT = 5
ctypedef unsigned long long word_t
Run Code Online (Sandbox Code Playgroud)
这样一种方式,IFCython不会"处理"它,但它是通过并在最终的C文件中有相同的代码吗?
我不会使用预处理器来定义大小和移位值,而是vector_length稍微更改您的函数,以便它可以sizeof直接使用。Cython 将正确翻译运算符,并且编译器将在编译时sizeof替换类型的实际大小。有关使用和获取正确向量大小的更多信息,请参阅 glibc 文档中的本节:https: //www.gnu.org/software/libc/manual/html_node/Width-of-Type.html。sizeofCHAR_BIT
from libc.stdlib cimport calloc, free
from libc.limits cimport CHAR_BIT
ctypedef unsigned long long word_t
cdef size_t vector_length(size_t bit_size):
cdef size_t bits_per_word = CHAR_BIT*sizeof(word_t)
return (bit_size + bits_per_word - 1) / bits_per_word
cdef class BitVector(object):
cdef size_t length
cdef size_t array_size
cdef word_t *array
def __cinit__(self, size_t size):
self.length = size
self.array_size = vector_length(size)
self.array = <word_t *>calloc(self.array_size, sizeof(word_t))
def __dealloc__(self):
free(self.array)
Run Code Online (Sandbox Code Playgroud)
还值得注意的unsigned long long是至少是 64 位(https://en.wikipedia.org/wiki/C_data_types)。您的代码似乎假设它可以是64位或 32 位,但在符合标准的编译器中它只能是 64 位或更多。
| 归档时间: |
|
| 查看次数: |
1038 次 |
| 最近记录: |