我提前为我对C的不良知识道歉:我使用Python编写代码并使用标准C函数编写了一些Cython模块,以大大提高速度。但是,我需要一个高于1e308
的范围(是的,你读得对),这是我目前通过使用类型double complex
以及函数cexp
和{{1}获得的范围}。
我尝试使用函数cabs
和cexpl
,并声明我的变量属于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;
}
所以我猜问题出在我的代码中,是吗?除了声明变量以确保我的程序实际使用长双精度之外,是否还需要添加任何显式标识符?
答案 0 :(得分:2)
正如在问题的编辑中看到的那样,我的系统和编译器通过打印long double
的正确范围而按预期运行,相关变量为LDBL_MAX = 1.189731e+4932
此外,使用Cython编写的模块正确地提供了类型long double
的输出。
但是,由于Python本身不支持此类型(请参阅this问题),因此返回的值大于系统上double
,1.797693E+308
的最大大小,因此等同于+inf + 0j
。所以这与gcc根本无关,而是与Python以不正确的方式解释长双打。
我希望通过使用另一个可以接受长双输入类型并进一步处理它的C模块来解决这个问题,这个子部分的预期结果预计不会超出double
的范围。 (或者就此而言,即使是float
)。
另一种选择可能是使用Python的库,它可以支持高精度和高范围的数字,可能是GMPY。