如何使用Cython强制使用长双打?

时间:2014-08-19 09:31:24

标签: c gcc cython long-double

我提前为我对C的不良知识道歉:我使用Python编写代码并使用标准C函数编写了一些Cython模块,以大大提高速度。但是,我需要一个高于1e308的范围(是的,你读得对),这是我目前通过使用类型double complex以及函数cexp和{{1}获得的范围}。

我尝试使用函数cabscexpl,并声明我的变量属于cabsl类型,但我仍然在long double complex之后遇到溢出。这可能意味着我的编译器将长双精度转换为双精度数,是吗?但根据维基百科,

  

使用GNU C编译器,x86处理器的长双精度是80位扩展精度,无论该类型使用的物理存储器是什么(可以是96位或128位)。[4]

我正在使用带有Linux Linux的64位系统(如果重要的话,还有Python 2.7.8)。

如何编写强制使用长双打的Cython模块?对于我正在做的一些科学计算,我需要这么大的数字。

修改 使用标志-m128bit-long-double进行编译会得到相同的结果。如上所示here

  

在x86-64编译器中,-m128bit-long-double是默认选择,因为它的ABI指定long double要在16字节边界上对齐。

所以这似乎没什么区别。

我还运行了以下程序来检查系统上的范围:

1e308

并获得以下输出:

#include <stdio.h>
#include <float.h>

int main()
{
   printf("Storage size for float : %d \n", sizeof(float));
   printf("Minimum float positive value: %E\n", FLT_MIN );
   printf("Maximum float positive value: %E\n", FLT_MAX );
   printf("Precision value: %d\n", FLT_DIG );

   printf("Storage size for double : %d \n", sizeof(double));
   printf("Minimum double positive value: %E\n", DBL_MIN );
   printf("Maximum double positive value: %E\n", DBL_MAX );
   printf("Precision value: %d\n", DBL_DIG );

   printf("Storage size for long double : %d \n", sizeof(long double));
   printf("Minimum long double positive value: %Le\n", LDBL_MIN );
   printf("Maximum long double positive value: %Le\n", LDBL_MAX );
   printf("Precision value: %d\n", LDBL_DIG );

   return 0;
}

所以我猜问题出在我的代码中,是吗?除了声明变量以确保我的程序实际使用长双精度之外,是否还需要添加任何显式标识符?

1 个答案:

答案 0 :(得分:2)

正如在问题的编辑中看到的那样,我的系统和编译器通过打印long double的正确范围而按预期运行,相关变量为LDBL_MAX = 1.189731e+4932

此外,使用Cython编写的模块正确地提供了类型long double的输出。 但是,由于Python本身不支持此类型(请参阅this问题),因此返回的值大于系统上double1.797693E+308的最大大小,因此等同于+inf + 0j。所以这与gcc根本无关,而是与Python以不正确的方式解释长双打。

我希望通过使用另一个可以接受长双输入类型并进一步处理它的C模块来解决这个问题,这个子部分的预期结果预计不会超出double的范围。 (或者就此而言,即使是float)。

另一种选择可能是使用Python的库,它可以支持高精度和高范围的数字,可能是GMPY