Quad-precision numbers with Intel Compiler (icc)

591 views Asked by At

I have been trying to work with Intel's Quad-precision floats. I have the following code, and it is returning unexpected results.

#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: %s\n", 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));
}

This program returns the following results:

value: +3.141592653589793238462643383279502797e+00   
log: +7.644623500000000000000000000000000000e+07   
log10: -6.174980530000000000000000000000000000e+08   
cos: +0.000000000000000000000000000000000000e+00   
sin: +0.000000000000000000000000000000000000e+00   
sqrt: -1.994699018000000000000000000000000000e+09   

It looks like the quad-precision literal is being interpreted correctly. However, the functions logq, log10q, cosq, sinq and sqrtq are returning incorrect results.

The only directions I've found regarding Intel's _Quad type is here.

I am compiling this code on MacOS with:

icc -fPIC -wd1572 -Qoption,cpp,--extended_float_type -Wconversion -lquadmath -L/usr/local/Cellar/gcc/10.2.0/lib/gcc/10 test.c

Am I using the quad-precision math functions correctly?

Also, I have tried to use the function pattern as described in this post.

Quadruple precision analogs of libm functions have '__' prefix (double underscore) and 'q' suffix."

However, this results in NaN returned for all functions.

2

There are 2 answers

0
user1998863 On

I have encountered similar issues using Visual Studio with Intel C++ compiler 2021. Here is an example that I think may be a bug in 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 = %d\n", (double)nn, mm1, mm2);
}

In 32-bit release, it prints:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!nn = 23.1416, mm1 = 1, mm2 = 2

In 32-bit debug, it prints:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!nn = 23.1416, mm1 = 4266, mm2 = 4267

In 64-bit debug and release, it prints:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!nn = 23.1416, mm1 = 1, mm2 = 2

1
maybourne On

You need to declare the functions and you do need the '__' prefix. E.g:

extern "C" _Quad __logq(_Quad x) ;

This works on Windows. Can't see why it wouldn't work on a Mac.