Как использовать Gcc 4.6.0 libquadmath и __float128 на x86 и x86_64 - PullRequest
13 голосов
/ 23 июня 2011

У меня есть программа C99 среднего размера, которая использует long double тип (80 бит) для вычисления с плавающей запятой.Я хочу повысить точность с новым расширением GCC 4.6 __float128.Насколько я понимаю, это математическая программа с 128-битной точностью.

Как мне преобразовать мою программу из классического длинного двойного 80-битного в четырехплавающее 128-битное с программной эмуляцией полной точности?Что мне нужно изменить?Флаги компилятора, источники?

Моя программа считывает значения полной точности с помощью strtod, выполняя множество различных операций над ними (например, + - * / sin, cos, exp и другие из <math.h>printf -из них.

PS: несмотря на то, что float128 объявлен только для Fortran (REAL * 16), libquadmath написан на C и использует float128.Я не уверен, что GCC преобразует операции на float128 в библиотеку времени выполнения или нет, и я не уверен, как перейти с long double на __float128 в моих источниках.

PPS: есть документация по языку "C" gccрежим: http://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html

"Компилятор GNU C поддерживает ... 128-битные (TFmode) плавающие типы. Поддержка дополнительных типов включает арифметические операторы: сложение, вычитание, умножение, делим ; унарные арифметические операторы; реляционные операторы; операторы равенства ... __float128 типы поддерживаются на i386, x86_64 "

1 Ответ

24 голосов
/ 04 апреля 2014

Как мне преобразовать мою программу из классического длинного двойного 80-битного в четырехплавающее 128-битное с программной эмуляцией полной точности? Что мне нужно изменить? Флаги компилятора, исходники?

Вам необходимо новейшее программное обеспечение, версия GCC с поддержкой типа __float128 (4.6 и новее) и libquadmath (поддерживается только для целей x86 и x86_64 ; в IA64 и HPPA с более новым GCC). Вы должны добавить флаг компоновщика -lquadmath (cannot find -lquadmath' покажет, что у вас не установлен libquadmath)

  • Добавьте заголовок #include <quadmath.h>, чтобы иметь определения макросов и функций.
  • Вы должны изменить все long double определения переменных на __float128.
  • Сложные переменные могут быть изменены на тип __complex128 (quadmath.h) или напрямую с помощью typedef _Complex float __attribute__((mode(TC))) _Complex128;
  • Все простые арифметические операции автоматически обрабатываются GCC (преобразуются в вызовы вспомогательных функций, таких как __*tf3()).
  • Если вы используете какой-либо макрос, например LDBL_*, замените его на FLT128_* (полный список http://gcc.gnu.org/onlinedocs/libquadmath/Typedef-and-constants.html#Typedef-and-constants)
  • Если вам нужны определенные константы, такие как pi (M_PI) или e (M_E) с четверной точностью, используйте предопределенные константы с суффиксом q (M_*q), например M_PIq и M_Eq ( полный список http://gcc.gnu.org/onlinedocs/libquadmath/Typedef-and-constants.html#Typedef-and-constants)
  • Пользовательские константы могут быть записаны с суффиксом Q, например 1.3000011111111Q
  • Все вызовы математических функций должны быть заменены *q версиями, такими как sqrtq(), sinq() (полный список http://gcc.gnu.org/onlinedocs/libquadmath/Math-Library-Routines.html#Math-Library-Routines)
  • Чтение quad-float из строки должно выполняться с помощью __float128 strtoflt128 (const char *s, char **sp) - http://gcc.gnu.org/onlinedocs/libquadmath/strtoflt128.html#strtoflt128 (Внимание, в старых библиотеках libquadmaths могут быть некоторые ошибки в strtoflt128, выполните двойную проверку)
  • Печать __float128 выполняется с помощью функции quadmath_snprintf. В дистрибутивах Linux с недавним glibc функция будет автоматически зарегистрирована libquadmath для обработки Q (может быть также q) модификатора длины a, A, e, E, f, F, g, G спецификаторов преобразования во всех printf s / sprintf s, как это и было L для длинных пар. Пример: printf ("%Qe", 1.2Q), http://gcc.gnu.org/onlinedocs/libquadmath/quadmath_005fsnprintf.html#quadmath_005fsnprintf

Вы также должны знать, что с 4.6 Gfortran будет использовать тип __float128 для ДВОЙНОЙ ТОЧНОСТИ, если была задана опция -fdefault-real-8 и не было опции -fdefault-double-8. Это может быть проблемой, поскольку 128 long double намного медленнее, чем стандартный long double на многих платформах из-за программных вычислений. (Спасибо за сообщение от glennglockwood http://glennklockwood.blogspot.com/2014/02/linux-perf-libquadmath-and-gfortrans.html)

...