Числа с точностью до четырех с помощью компилятора Intel (icc)

#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