问题
I apologize in advance for my poor knowledge of C: I use Python to code and have written a few modules with Cython using the standard C functions to effect a great increase in speed. However, I need a range higher than 1e308
(yes, you read it right), which is what I currently get by using the type double complex
and the functions cexp
and cabs
.
I tried to use the functions cexpl
and cabsl
, and declared my variables to be of type long double complex
, but I still encounter overflows after 1e308
. This probably means that my compiler converts long doubles to doubles, is that right? But according to Wikipedia,
With the GNU C Compiler, long double is 80-bit extended precision on x86 processors regardless of the physical storage used for the type (which can be either 96 or 128 bits)..[4]
I am using a 64-bit system with arch Linux (and Python 2.7.8 if it matters).
How do I write a Cython module that forces the use of long doubles? I need such big numbers for some scientific computation I am doing.
Edit: Compiling with the flag -m128bit-long-double gives the same result. As indicated here,
In the x86-64 compiler, -m128bit-long-double is the default choice as its ABI specifies that long double is to be aligned on 16 byte boundary.
So this seems to make no difference.
I also ran this following program to check the range on my system:
#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;
}
and got the following output:
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
So I guess the problem lies in my code, is that right? Are there any explicit identifiers I need to add other than declaring variables to ensure that my program actually uses long doubles?
回答1:
As was seen in the edit to the question, my system and compiler was behaving as expected by printing the correct range for long double
, the relevant variable here being LDBL_MAX = 1.189731e+4932
Also, the module written with Cython was correctly giving an output of type long double
.
However, since this type is not natively supported in Python (see this question), the value that was returned was greater than the maximum size of double
,1.797693E+308
on my system and hence being equated to +inf + 0j
. So this was not related to gcc at all, but to Python interpreting long doubles in an incorrect way.
I can hopefully get around this by working with another C module that can accept long double input types and process it further, the expected results from this sub-part is not expected to be outside the range of a double
(or for that matter, even a float
).
Another option might be to use libraries with Python that can support high precision and high range numbers, possibly GMPY.
来源:https://stackoverflow.com/questions/25380004/how-do-i-force-usage-of-long-doubles-with-cython