Как заставить использование длинных пар с Cython?

Заранее извиняюсь за плохое знание C: я использую Python для написания кода и написал несколько модулей на Cython, используя стандартные функции C, чтобы добиться значительного увеличения скорости. Однако мне нужен диапазон выше, чем 1e308 (да, вы правильно прочитали), что я сейчас получаю, используя тип double complex и функции cexp а также cabs,

Я пытался использовать функции cexpl а также cabslи объявил мои переменные типа long double complex, но я все еще сталкиваюсь с переполнением после 1e308, Это, вероятно, означает, что мой компилятор конвертирует длинные двойные числа в двойные, верно? Но согласно Википедии,

В компиляторе GNU C long double - это 80-битная расширенная точность на процессорах x86, независимо от физической памяти, используемой для типа (которая может быть 96 или 128 битами).[4]

Я использую 64-битную систему с Arch Linux (и 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

Так что я думаю, проблема в моем коде, верно? Есть ли какие-то явные идентификаторы, которые мне нужно добавить, кроме объявления переменных, чтобы моя программа действительно использовала длинные двойные числа?

1 ответ

Решение

Как видно из редактирования вопроса, моя система и компилятор работали так, как ожидалось, печатая правильный диапазон для long doubleсоответствующая переменная здесь LDBL_MAX = 1.189731e+4932

Кроме того, модуль, написанный на Cython, правильно выдавал вывод типа long double, Однако, поскольку этот тип изначально не поддерживается в Python (см. Этот вопрос), возвращаемое значение было больше максимального размера double,1.797693E+308 в моей системе и, следовательно, приравнивается к +inf + 0j, Так что это вообще не было связано с gcc, а с Python, неправильно интерпретирующим длинные двойные числа.

Надеюсь, я смогу обойти это, работая с другим модулем C, который может принимать длинные двойные типы ввода и обрабатывать его дальше; ожидаемые результаты из этой части не должны выходить за пределы диапазона double (или в этом отношении, даже float).

Другой вариант может заключаться в использовании библиотек с Python, которые могут поддерживать числа высокой точности и диапазона, возможно, GMPY.

Другие вопросы по тегам