4

对于我对 C 的了解不足,我提前道歉:我使用 Python 编写代码,并使用标准 C 函数使用 Cython 编写了一些模块,以大大提高速度。但是,我需要一个高于1e308 (是的,你没看错)的范围,这是我目前通过使用类型double complex和函数cexpcabs.

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

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

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

如何编写强制使用长双打的 Cython 模块?我需要这么大的数字来进行一些科学计算。

编辑: 使用标志 -m128bit-long-double 编译会得到相同的结果。如此处所示,

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

所以这似乎没有什么区别。

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

#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;
}

并得到以下输出:

Storage size for float : 4 
Minimum float positive value: 1.175494E-38
Maximum float positive value: 3.402823E+38
Precision value: 6
Storage size for double : 8 
Minimum double positive value: 2.225074E-308
Maximum double positive value: 1.797693E+308
Precision value: 15
Storage size for long double : 16 
Minimum long double positive value: 3.362103e-4932
Maximum long double positive value: 1.189731e+4932
Precision value: 18

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

4

1 回答 1

2

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

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

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

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

于 2014-08-19T18:29:54.003 回答