#c #floating-point #ieee-754 #icc #quadruple-precision
#c #с плавающей запятой #ieee-754 #icc #четырехкратная точность
Вопрос:
Я пытался работать с числами с плавающей запятой Intel с точностью до четырех. У меня есть следующий код, и он возвращает неожиданные результаты.
#include <stdio.h>
#include <math.h>
int print(const char *label, _Quad r) {
int prec = 20;
int width = 46;
char buf[128];
int n = quadmath_snprintf(buf, sizeof buf, "% -#*.36Qe", width, r);
printf ("%s: %sn", label, buf);
return 0;
}
int main () {
_Quad x = 3.14159265358979323846264338327950288q;
print("value", x);
print("log", logq(x));
print("log10", log10q(x));
print("cos", cosq(x));
print("sin", sinq(x));
print("sqrt", sqrtq(x));
}
Эта программа возвращает следующие результаты:
value: 3.141592653589793238462643383279502797e 00
log: 7.644623500000000000000000000000000000e 07
log10: -6.174980530000000000000000000000000000e 08
cos: 0.000000000000000000000000000000000000e 00
sin: 0.000000000000000000000000000000000000e 00
sqrt: -1.994699018000000000000000000000000000e 09
Похоже, что литерал с точностью до четырех интерпретируется правильно. Однако функции logq
, log10q
, cosq
, sinq
и sqrtq
возвращают неправильные результаты.
Единственные указания, которые я нашел относительно _Quad
типа Intel, находятся здесь.
Я компилирую этот код на macOS с:
icc -fPIC -wd1572 -Qoption,cpp,--extended_float_type -Wconversion -lquadmath -L/usr/local/Cellar/gcc/10.2.0/lib/gcc/10 test.c
Правильно ли я использую математические функции с точностью до четырех?
Кроме того, я попытался использовать шаблон функции, как описано в этом сообщении .
Аналоги функций libm с четырехкратной точностью имеют префикс «__» (двойное подчеркивание) и суффикс «q «.»
Однако это приводит к NaN
возврату для всех функций.
Ответ №1:
Вам нужно объявить функции, и вам нужен префикс ‘__’. Например:
extern "C" _Quad __logq(_Quad x) ;
Это работает в Windows. Не понимаю, почему это не будет работать на Mac.
Комментарии:
1. Почему
extern "C"
для компиляции C?
Ответ №2:
Я столкнулся с аналогичными проблемами при использовании Visual Studio с компилятором Intel C 2021. Вот пример, который, я думаю, может быть ошибкой в ICC.
_Quad nn = 23.1416Q;
int mm1 = (int)(double)__log10q(nn); // there is a bug in Intel 2021 compiler. need to do cast here
int mm2 = __log10q(nn);
if (mm1 != mm2) {
printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!nn = %g, mm1 = %d, mm2 = %dn", (double)nn, mm1, mm2);
}
В 32-разрядной версии он печатает:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!nn = 23.1416, mm1 = 1, mm2 = 2
В 32-разрядной отладке он печатает:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!nn = 23.1416, mm1 = 4266, mm2 = 4267
При 64-разрядной отладке и выпуске он печатает:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!nn = 23.1416, mm1 = 1, mm2 = 2