如何构造小数.十进制对象使用的C API?



我有兴趣在c的扩展中创建decimal.Decimal对象。我在文档

中找不到关于此的任何文档。有相关的文档吗?有其他例子吗?

我已经在Python git存储库中找到了实现该对象的源代码,因此我确信我可以做一些试验和错误,并通过处理头文件导入来混淆,但首选文档(如果存在的话)。

在Python 3.10中,将会有一个C API用于此。您需要提供自己的libmpdec和mpdecimal.h头文件,并使用import_decimal()初始化十进制API。(请注意,c级import_decimal()调用与python级语句import decimal完全不同,并且与之无关。)

设置完成后,可以使用

分配未初始化的Decimal对象。
PyObject *dec = PyDec_Alloc();
然后用 获取一个指向内部mpd_t的指针
mpd_t *dec_internal = PyDec_Get(dec);

并使用libmpdec函数初始化mpd_t。(注意,十进制对象在逻辑上是不可变的,所以除了用PyDec_Alloc分配的对象之外,您应该避免改变任何十进制对象。)

要使用现有Decimal对象的mpd_t,可以执行

const mpd_t *dec_internal = PyDec_GetConst(some_existing_decimal);

,然后使用非变化的libmpdec函数。


对于3.10之前的代码,没有Decimal C API。你只需要使用PyImport_ImportModulePyObject_GetAttrStringPyObject_Call这样的函数来完成c级的import decimal; d = Decimal(whatever)

您的问题是关于decimal.Decimal类,而链接的代码指向使用库libmpdec的优化模块_decimal

下面的代码片段将在Python 3.9中适用于所有三种情况(decimal/_decimal/_pydecimal)。

PyObject *module = PyImport_ImportModule((char *) "decimal");
PyObject *clazz = PyObject_GetAttrString(module, (char *) "Decimal");
PyObject *value = PyUnicode_FromString("123.45");
PyObject *object = PyObject_CallOneArg(clazz, value);
PyObject  *str = PyObject_Str(object);
// C++
std::cout << "dec: " << PyUnicode_AsUTF8(str) << std::endl;
// C
// printf("dec: %sn", PyUnicode_AsUTF8(str));

输出:

dec: 123.45

关于Python 3.3中_decimal实现的一些背景信息可以在https://bugs.python.org/issue7652

找到。

最新更新