用c扩展python时,如何处理任意大小的整数?
Python/capi手册提到了⁽¹⁾ 以及⁽²⁾ void指针,这似乎是在C中使用任意长度python整数的唯一方法。用c扩展python时,如何处理任意大小的整数?,python,c,python-3.x,long-integer,arbitrary-precision,Python,C,Python 3.x,Long Integer,Arbitrary Precision,Python/capi手册提到了⁽¹⁾ 以及⁽²⁾ void指针,这似乎是在C中使用任意长度python整数的唯一方法。 (1) :PyLong\u FromVoidPtr()并使用Py\u BuildValue()格式化0& (2) :PyLong\u AsVoidPtr()和格式0,0&和0带有PyArg\uux…Parse…() 但是,我还没有找到⁽³⁾ 在手册中,任何关于如何使用这些空指针在C中对这些任意长整数执行任何操作的指示。 (3) :我尝试搜索了«voidptr»、«void*
(1) :
PyLong\u FromVoidPtr()
并使用Py\u BuildValue()格式化0&
(2) :PyLong\u AsVoidPtr()
和格式0
,0&
和0代码>带有PyArg\uux…Parse…()
但是,我还没有找到⁽³⁾ 在手册中,任何关于如何使用这些空指针在C中对这些任意长整数执行任何操作的指示。
(3) :我尝试搜索了«voidptr»、«void*»和«0&»,但还没有完全阅读
我在哪里可以找到关于它们的内部结构或原语的信息来进行计算呢?实际上,这些函数并没有“指向任意大整数的指针”,而是字面上的整数值,如void*
指针,如中所示,铸造到类型void*
。请参阅和的实现。它只允许您在Python中保存任意指针,确保正确完成转换
据我所知,从Python中获取任意长整数最实用的方法是使用and。实际上,有一个内部ish API/可供您使用。见相关问题
注意:有趣的是,似乎没有任何官方或其他的C API来告诉Python整数值的位或字节长度。Python中有,但它似乎没有映射到任何公开可用的函数。在Include/longintrepr.h
中有文档:
/* Parameters of the integer representation. There are two different
sets of parameters: one set for 30-bit digits, stored in an unsigned 32-bit
integer type, and one set for 15-bit digits with each digit stored in an
unsigned short. The value of PYLONG_BITS_IN_DIGIT, defined either at
configure time or in pyport.h, is used to decide which digit size to use.
Type 'digit' should be able to hold 2*PyLong_BASE-1, and type 'twodigits'
should be an unsigned integer type able to hold all integers up to
PyLong_BASE*PyLong_BASE-1. x_sub assumes that 'digit' is an unsigned type,
and that overflow is handled by taking the result modulo 2**N for some N >
PyLong_SHIFT. The majority of the code doesn't care about the precise
value of PyLong_SHIFT, but there are some notable exceptions:
- long_pow() requires that PyLong_SHIFT be divisible by 5
- PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8
- long_hash() requires that PyLong_SHIFT is *strictly* less than the number
of bits in an unsigned long, as do the PyLong <-> long (or unsigned long)
conversion functions
- the Python int <-> size_t/Py_ssize_t conversion functions expect that
PyLong_SHIFT is strictly less than the number of bits in a size_t
- the marshal code currently expects that PyLong_SHIFT is a multiple of 15
- NSMALLNEGINTS and NSMALLPOSINTS should be small enough to fit in a single
digit; with the current values this forces PyLong_SHIFT >= 9
The values 15 and 30 should fit all of the above requirements, on any
platform.
*/
有一个成员将以字节表示大小-因此,如果PYLONG\u BITS\u in\u DIGIT
为30,ob\u DIGIT
是一个ob\u size/sizeof(uint32\u t)
uint32\u t
s的数组,每个数组中有30位有效;否则,ob\u digit
是ob\u size/sizeof(uint16\u t)
uint16\u t
s的数组,每个数字中存储15个有效位
这都是Include/longintrepr.h
的一部分,但它们仅在中显示#ifndef Py_LIMITED_API
似乎没有任何官方或其他的C API来告诉整数的位或字节长度。在C语言中,sizeof(int)
返回int
的大小(以字节为单位)。@AndrewHenle对不起,我指的是Python整数值,它可以有任意位数(现在更清楚了)。
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};