【发布时间】:2014-08-19 09:31:24
【问题描述】:
我提前为我对 C 的了解不足深表歉意:我使用 Python 编写代码,并使用标准 C 函数使用 Cython 编写了一些模块,以显着提高速度。但是,我需要一个高于1e308 的范围(是的,你没看错),这是我目前通过使用double complex 类型和函数cexp 和cabs 得到的。
我尝试使用函数cexpl 和cabsl,并将我的变量声明为long double complex 类型,但在1e308 之后仍然遇到溢出。这可能意味着我的编译器将长双精度转换为双精度,对吗?但根据维基百科,
使用 GNU C 编译器,long double 是 x86 处理器上的 80 位扩展精度,与用于该类型的物理存储(可以是 96 位或 128 位)无关。[4]
我使用的是 64 位系统和 arch Linux(如果重要的话,还有 Python 2.7.8)。
如何编写强制使用长双精度的 Cython 模块?我需要这么大的数字来进行一些科学计算。
编辑: 使用标志 -m128bit-long-double 编译会得到相同的结果。如here所示,
在 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
所以我猜问题出在我的代码上,对吗?除了声明变量以确保我的程序实际使用长双精度外,我还需要添加任何显式标识符吗?
【问题讨论】:
-
我没有把它作为答案,因为我不确定它是否正确......但如果你可以添加编译器标志,请尝试
-m96bit-long-double或-m128bit-long-double看看会发生什么. This question might be useful as well.祝你好运。 -
感谢您的指导!我更新了问题。如何检查我的编译器 (gcc) 是否真的使用 80 位或 96 位长双精度,范围在
1e4392左右,除了溢出? -
我发现 this question 表明我的 C 模块正在返回长双精度,但被 Python 解释为
inf,因为它超过了double的大小。就目前而言,我的问题并不是真正正确的问题,因为它建立在一个错误的前提下。我如何投票关闭它?还是应该让这个问题留给其他可能有同样想法的人? -
感谢您投入工作并找出问题所在。如果我是你,我会写下我的解决方案,将其作为答案发布,并接受它以供将来参考。这种做法在 SO 上是 actively supported。
标签: c gcc cython long-double