gpt4 book ai didi

cython - 在 Cython 中在编译时获取整数的大小

转载 作者:行者123 更新时间:2023-12-03 14:45:49 31 4
gpt4 key购买 nike

是否有可能,如果是,如何确定 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)

我需要处理数组元素的单个位和元素本身,因此我必须知道它们包含多少位(以计算正确的掩码/移位)。尝试编译像上面这样的代码会产生:
$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

有没有可行的替代方案?

我知道有一个 stdint.h应该定义整数类型的 header ,但我想不出使用它的方法,因为:
  • 我不知道如何检查是否未定义类型(例如,您如何在 cython 中编写 IF uint64_t is not defined:?)。
  • Cython 的文档指出只有 DEF 定义的东西并且可以在IF中检查编译器s,因此我怀疑我是否能够使用 stdint.h反正。


  • 这在 Cython 中似乎不可行,因为我想要进行的检查只能在从 C 编译为机器代码时执行,而不能从 cython 编译为 C。

    现在我想知道:是否有可能以在 C 源代码中添加这种检查的方式编写 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

    以这样的方式,这个 IF Cython“未处理”,但它通过并且在最终的C文件中有等效的代码?

    最佳答案

    我将更改您的 vector_length,而不是使用预处理器来定义大小和移位值。稍加功能,以便它可以使用 sizeof直接地。 Cython 将翻译 sizeof运算符正确,编译器将在编译时替换类型的实际大小。有关使用 sizeof 的更多信息,请参阅 glibc 文档中的这一部分。和 CHAR_BIT获得正确的向量大小:https://www.gnu.org/software/libc/manual/html_node/Width-of-Type.html .

    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)

    还值得注意的是 unsigned long long至少是 64 位 ( https://en.wikipedia.org/wiki/C_data_types )。您的代码似乎假定它可以是 64 位或 32 位,但在符合标准的编译器中,它只会是 64 位或更多。

    关于cython - 在 Cython 中在编译时获取整数的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15765509/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com