Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用c扩展python时,如何处理任意大小的整数?_Python_C_Python 3.x_Long Integer_Arbitrary Precision - Fatal编程技术网

用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*

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*»和«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];
};