no quadruple precisionin icc! icc versus ifort

no quadruple precisionin icc! icc versus ifort

I have just checked that ifort compiler supports quadruple precision (real*16) and keeps 35 digits while icc compiler with 'long double' supports only 20 digits which is actually not a quadruple precision. The test was done at the x86_64 latitude laptop. What is the reason of the problem and how to fix it. I would like to have quadruple precision
with icc compiler which is eventually not supported with 'long double'

6 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

ifort real*16 (113 bits precision) is implemented on Xeon CPUs by functions which combine x87 operations, so the performance is quite low in comparison with vectorizable code. ia64 implementation is better, but still not fantastic. There are no corresponding C or C++ math or char to binary conversion functions, no STL support, nor any MS or gcc compatibility. It doesn't coexist with the faster gcc-compatible 80-bit long double (enabled by icc -long-double). In summary, it is not very useful without ifort.
Documentation is minimal and has restricted distribution; if you have paid support you could request the "black-belt" .pdf on your account, explaining (and attempting to persuade) about your intended use. It still won't be supported, i.e. if it's broken in your usage, it's broken. gmp/mpfr are much more popular for multiple precision.

Hi, belyaev!
Intel C++ Compiler has the stuff you need!
To enable 128-bit FP type (analog Fortran's REAL*16) usage, specify compiler switch
To declare the required data type, use keyword '_Quad'.
To specify quadrupple constant, use 'q' suffix (3.1415926q).
Quadrupple analogs of Libm functions have '__' prefix (double underscore)
and 'q' suffix. For example,
_Quad __sqrtq (_Quad x);
is quadrupple analog for double 'sqrt'.
Unfortunately, this type is not supported by scanf/printf, but it's not so critical drawback -- it's quite easy to write _Quad <-> text fixed-format convertors and use them with %s format specifier.
Almost all other needed stuff is presented -- already mentioned Libm functions, arithmetic, comparisons and conversions to/from all main integer and fp types (via cast operator).
So, it's quite sterling data type!
And, of course, it isn't related with 'long double' type.

Here is small sample, which illustrates some aspects of _Quad usage.
Try to compile it by:

>icc(/icl) -Qoption,cpp,--extended_float_type quad.c

then run and learn

/* quad.? -- how _Quad type may be useful sometimes */

double d_hypot (double x, double y);
double q_hypot (double x, double y);
_Quad __sqrtq (_Quad x);

int main (void)
double x = 3.e+300;
double y = 4.e+300;

printf ("Args: x = %e, y = %e
", x, y);
printf ("Result (d_hypot): %e
", d_hypot(x, y));
printf ("Result (q_hypot): %e
", q_hypot(x, y));
return 0;

double d_hypot (double x, double y)
return sqrt (x*x + y*y);

double q_hypot (double x, double y)
double result = d_hypot(x, y);

if (isinf(result)) {
_Quad qx = (_Quad) x;
_Quad qy = (_Quad) y;

return (double) __sqrtq (qx*qx + qy*qy);
return result;

Good luck!

Dear Pew,

thanks a lot for your help! I took a look at your reply only recently. It is a great help for our current research devoted to linear collider High Energy studies which required quadruple precision!

Everything works -- in Fortran and in C. Since our new software is C-based
your help with C -- is really great deal. As I understood "_Quad" type is an Intel specific as well as compiler options. Anyway we did a big breakthrough
in our research due to the help from your side! Thanks a lot again,

Alexander (

What the status of this in modern versions of icc. In (ICC) 12.1.3 20120212 --extended_float_type and _Quad are not recognised. The manual is also extremely annoying. However much you search for "float", "real", "quad" you can't find what dataypes are suported. it should clearly say for example that long double is 10 bytes of precision though for some crazy reason it is stored in 16 bytes. If quad precision is not available it should say so one doesn't just have to keep searching.

You may call it crazy, but 10-byte long double (64 bit precision, 8 bytes to most people) has to be aligned consistently with the corresponding gcc. 16 byte alignment gives better performance as it avoids splitting cache lines. 12 byte alignment, as it used to be in the 32-bit compilers, allows for sharing storage with int in a struct or union without too much confusion.
16-byte long double, consistent with ifort real*16, has never been supported to the extent that it could be documented in the manual. You may as well use gcc for that purpose; icc would not have any special optimizations, since there is no vectorization or interface with asm-like intrinsics.

Leave a Comment

Please sign in to add a comment. Not a member? Join today