Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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
Python C API检查int64是否未签名_Python_C - Fatal编程技术网

Python C API检查int64是否未签名

Python C API检查int64是否未签名,python,c,Python,C,我正在使用Python C API编写一个Python3脚本,其中包含一些计算量很大的C部分。在处理int64时,我不知道如何确保输入数字是无符号int64;也就是说,如果它小于0。正如所建议的,我正在将PyArg\u ParseTuple()。这是我的C代码: static PyObject* from_uint64(PyObject* self, PyObject*){ uint64_t input; PyObject* output; if (!PyArg_Par

我正在使用Python C API编写一个Python3脚本,其中包含一些计算量很大的C部分。在处理int64时,我不知道如何确保输入数字是无符号int64;也就是说,如果它小于0。正如所建议的,我正在将
PyArg\u ParseTuple()。这是我的C代码:

static PyObject* from_uint64(PyObject* self, PyObject*){
    uint64_t input;
    PyObject* output;

    if (!PyArg_ParseTuple(args, "K", &input)){
        return PyErr_Format(PyExc_ValueError, "Wrong input: expected unsigned 64-bit integer.");
    }

    return NULL;
}
但是,使用负参数调用函数不会引发任何错误,并且输入数字被强制转换为无符号。例如,来自_uint64(-1)
将导致
输入=2^64-2
。正如所料,因为没有溢出检查

在解析输入数字之前,确定输入数字是否为负数的正确方法是什么

unsigned long long input = PyLong_AsUnsignedLongLong(args);
然后,您可以向

if (PyErr_Occurred()) {
    // handle out of range here
}
如果该数字不适合
无符号long


另请参见@Ctx的答案稍作修改后的内容:

解决方案是首先将输入解析为对象(因此,不是直接从
args
),然后检查其类型:

static PyObject* from_uint64(PyObject* self, PyObject* args){
    PyObject* output;
    PyObject* input_obj;
    if (!PyArg_ParseTuple(args, "O", &input_obj)){
        return PyErr_Format(PyExc_TypeError, "Wrong input: expected py object.");
    }
    unsigned long long input = PyLong_AsUnsignedLongLong(input_obj);
    if(input == -1 && PyErr_Occurred()) {
        PyErr_Clear();
        return PyErr_Format(PyExc_TypeError, "Parameter must be an unsigned integer type, but got %s", Py_TYPE
        (input_obj)->tp_name);
    }

正如预期的那样,此代码适用于[0,2^64-1]中的任何输入,并对边界外的整数以及浮点、字符串等非法类型抛出错误。

无符号整数不会溢出。C指定它们遵循模运算。还要注意,
K
不解析
uint64\u t
,而是解析
unsigned long
,因此假设
uint64\u t
与unsigned long long相同并不严格正确。@AnttiHaapala感谢您的更正,我将添加正确的类型。谢谢您的回答。我仍然存在的唯一问题是输入号码很小的情况-例如,如果从_uint64(2)
调用
,现在会抛出错误。我应该从Python中进行一些类型的转换吗?我要接受[0,2^64-1]范围内的任何数字。@FTeod引发了哪个错误?我看不出输入
2
有问题的原因。我得到
TypeError:需要一个整数
。代码是上面的三行,在
if(PyErr_occurrent()){PyErr_Print();return NULL;}