Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

80-bit long double trouble

firespot71
Beginner
2,939 Views
Hi,

Compiling a simple application with /Qlong-double (IA32, 12.1, integrated in MSVC on Win7 64-bit) and the two code lines below gives me a linker error on using std::numeric_limits<> when linking to multi-threaded debug DLLs (/MDd). Everything is fine if I link statically (/MTd). I suppose this is not intentional?


typedef long double real_type;
std::cout << std::numeric_limits::epsilon();

error LNK2019: unresolved external symbol "__declspec(dllimport) public: static UNKNOWN __cdecl std::numeric_limits::epsilon(void)" (__imp_?epsilon@?$numeric_limits@_T@std@@SA_TXZ)


Moreover, when using operator >> to read-in values with a long double variable as target, it reads rubbish or crashes.

real_type x;
std::cin >> x;
std::cout << x;

Entering '2.2' as input gives '-5.1488e-247' as output, which is quite different. I am not linking to any other file. Whether Intel links to a wrong MSVC-lib or not, I don't know, but I suppose Intel should get it right to linking to the correct lib as it has all the relevant info hany. Otherwise what runtime libs do I need to specify?


And finally: If linking to boost libraries, I strongly suppose that boost libraries must be built with the /Qlong-double option on to ensure binary compatibility - is that correct?


Any help appreciated !
Thanks.



0 Kudos
44 Replies
Bernard
Valued Contributor I
903 Views

Here is output with Microsoft C++ compiler ( Visual Studio 2005 ):


I'm aware that every compiler will be able tooperate on long double value as faras it is supported by the CPU(in our case X87 FPU with its 80-bit register file).
In order to fully understand how C++ cin and cout are implemented in Windows runtime libraries some kind of investigation must be performed.At least two subsystem dll's will be present and loaded into application address space:KERNEL32.DLL and USER32.DLL first of them is responsible for standard I/Oand is also imported from runtime library.
Bylooking at your test-case I can see that'cin' , 'cou't and 'printf' all of them are able to work with long double values so it could be asome problem related to Intel compiler?
0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
Quoting iliyapolak
...Bylooking at your test-case I can see that'cin' , 'cou't and 'printf' all of them are able to work with long double values so it could be asome problem related to Intel compiler?


It was confirmed by Georgsome time ago. Just for the sake of investigation theseare sizes for 'long double'for different C++ compilers:

[cpp]MSC/Intel C++ compilers - long double - 8 MinGW C++ compiler - long double - 12 Borland C++ compiler - long double - 10 Turbo C++ compiler - long double - 10 [/cpp]
0 Kudos
firespot71
Beginner
903 Views
If long double has sizeof(8) then as far as I know for both MSVC / Intel it is sort of equivalent to double. Sort of equivalent here means that they are different types in type matching (e.g. in template argument deductions; for example you could not invoke std::max(A, B) if A is double and B is long double, as the types mismatch) but binary implementation is identical and therefore should yield identical execution.

I suppose you have declared the types as long double but for Intel compiled without the /Qlong-double option; unless you set this option, by default long double maps to to the double type as outlined above. Therefore your test cases pass smoothly.

For Intel you can force a larger binary representation (80-bit, like your Borland and Turbo) by setting /Qlong-double. Then the types are different with respect to both type matching and binary representation (sizeof should be 10), and the whole trouble starts and I strongly guess that your test cases would not pass any more.

For MSVC there is, AFAIK, no possibility to forcing long-double to anything else than the double implementation. So you never run into compatibility problems, but also never get more than 64-bit (memory) precision. Your tests should always work.

0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
Quoting firespot71
...So you never run into compatibility problems, but also never get more than 64-bit (memory) precision...

It can't be more than a53-bit precision for the double-precision data types ( doubleor long double ).

Do you still have that linking problem?
0 Kudos
Bernard
Valued Contributor I
903 Views

MSC/IntelC++compilers-longdouble-8


So simply MS compilers are truncating precision of declared long double to 53-bit precision of double.
0 Kudos
firespot71
Beginner
903 Views
It can't be more than a53-bit precision for the double-precision data types ( doubleor long double ).

Do you still have that linking problem?

Precision should be implementation-dependent and I don't think an upper boundary is specified; although I don't know what Intel uses for 80-bit long double types, I'd strongly guess the mantissa takes more bits than for double. Anyway I was not expressing myself properly, I wanted to refer to the total number of bits comprising the data type (sign + mantissa + exponent).

Linker errors go away if I don't set the /Qlong-double option (as do all other errors); whether that is because the object files do contain proper definition for 64-bit long double or at some stage of the compilation / linking double and long double are set to being identical types if both share the same representation, or some other reason, I don't know. But as the DLLs don't link while static does, I don't think the second item of my list applies.

cheers

0 Kudos
TimP
Honored Contributor III
903 Views
I think we've beat this to death, but the documentation of /Qlong-double states (briefly) that the option breaks compatibility with Microsoft headers and libraries, on which ICL depends. This should be self-evident if you consider that Microsoft doesn't support 64-bit precision mode. You are over-riding Microsoft's required initialization to 53-bit precision mode, and use of SSE registers in /arch:SSE2 modes (including all X64 usage). If you choose to make the distinction between double and long double which Microsoft doesn't support, you must avoid mixing long double with Microsoft headers and functions compiled by MSVC (including libraries).
0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
Quoting iliyapolak

MSC/IntelC++compilers-longdouble-8


So simply MS compilers are truncating precision of declared long double to 53-bit precision of double.


Yes, that is correct and I was very surprised to see that. There is no any reason to use'long double' type in some application orlibrary
since 8 bytes are allocated for these data types.

For example, OpenGL designers / developersdidn'tdeclare 'long double' type at all:

>> GL.h<<
...
typedef float GLfloat;
typedef float GLclampf;
typedef double GLdouble;
typedef double GLclampd;
...

0 Kudos
firespot71
Beginner
903 Views

Yes, that is correct and I was very surprised to see that. There is no any reason to use'long double' type in some application orlibrary since 8 bytes are allocated for these data types.

For example, OpenGL designers / developersdidn'tdeclare 'long double' type at all:

Well I'd say it still makes sense in general but subject to practical constraints of course. For example one could do it as i) present code might be compiled with a compiler generally (fully) supporting > 8 bytes for this type (e.g. GCC family, or AFAIK also Intel on Linux), or ii) anticipating possible changes in future versions of MSVC / Intel-Win defaults, or iii) as Georg has pointed out, restricting long double use on Intel-Win with /Qlong-double specified to those functions supporting it. Indeed I have tried out the latter by doing precisely that an applying it in purely numerical sections where extra precision might matter. Conclusion: It does work without problems (except of needing to link statically, of course) yet in my case the performance penalty did not justify the virtually non-existant extra precision (in how far that penalty is due to more complex numerical routines invoked or the many casts between double and long double, I don't know). Other applications might draw differenct conclusions of course.

Note that technically MSVC and Intel's default option of 64-bit long doubles yet ar compliant with the C++ Standard as the long double requirements are fulfilled. Still I wished both would offer a fully compliant larger type and thus provide greater choice, but that's a differnt story.

Does OpenGL support long double on say GCC platforms? Otherwise, I suspect this might simply be due to standard graphics hardware not supporting floationg-point ops for > 64 bits (this is for sure not my field of expertise but are there any 'ordinary' customer graphics card out which do support standard > 64 bit calculations?)

0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
Quoting firespot71
...Does OpenGL support long double on say GCC platforms?..


No. OpenGL is a highly portable library andall type definitions are the same.For example, if some TypeA is supported
onPlatformA it is also supported on all the rest Platforms. If some TypeX is notsupported onPlatformA it is also notsupported
on all the rest Platforms.

0 Kudos
Bernard
Valued Contributor I
903 Views

For example, OpenGL designers / developersdidn'tdeclare 'long double' type at all:


Rendering API like OpenGL and DirectX do not need high precision long double primitives.
Display hardware is not capable to operate on more than 14-bit per channel RGBA vectors.
So you do not need 63-bit long double precision per channelto accurately describe more life-like colour or brightnessfields.
0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
Hi Iliya,

Quoting iliyapolak

For example, OpenGL designers / developersdidn'tdeclare 'long double' type at all:


Rendering API like OpenGL and DirectX do not need high precision long double primitives...

Some time in 2007 Idetectedthat'long double' data type is not declaredinOpenGL and Ididn't pay attention to it... What a great subject we have now! :)

Best regards,
Sergey
0 Kudos
Bernard
Valued Contributor I
903 Views

Some time in 2007 Idetectedthat'long double' data type is not declaredinOpenGL


@Sergey
Are you fluent in OpenGL programming?
Finally I have recieved F. Luna book on DirectX 11programming and this book coupled with Matt Pharr "Physically based rendering" will give me a lot of knowledge in the subject of computer graphics from the practical and theoretical point of view.
0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
Sorry. This is a test. Best regards, Sergey
0 Kudos
Bernard
Valued Contributor I
903 Views
>>>Some time in 2007 Idetected that'long double' data type is not declaredinOpenGL. I think that DirectX has 128-bit vector composed from 32-bit scalars representing clour components used by High Dynamic Range rendering.
0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
This is a test of posting a small test case: #include void main( void ) { printf("Hello New IDZ website...\n"); } I simply wanted to see how the new edit control re-formats the codes as soon as they are posted. By the way, what did happen with the old source codes editor? I really liked it... Best regards, Sergey
0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
What I can see that it deleted 'stdio.h' between 'arrow-left' and 'arrow-right'. Also, 5 space characters before 'printf' are also deleted...
0 Kudos
Bernard
Valued Contributor I
903 Views
@Sergey! Many of our posts simply disappeared when the forum was redesigned.Can you see this issue while looking at your posts?
0 Kudos
SergeyKostrov
Valued Contributor II
903 Views
>>...Many of our posts simply disappeared when the forum was redesigned.Can you see this issue while looking at your posts? >> I can't see any private posts as well.
0 Kudos
SergeyKostrov
Valued Contributor II
877 Views
This is a test of posting a small jpg-image and a small txt-file with a test-case. Unfortunately, upload of source files with extensions h, c and cpp is no longer allowed. ... A question to IDZ website developers: Why do we need a so "important" functionality like "Drag to re-order"?
0 Kudos
Bernard
Valued Contributor I
877 Views
>>...I can't see any private posts as well.
There is no such a option like a "private" post. @Sergey Two or three weeks ago you proposed a summary of my "Optimization of sine taylor expansion" thread. Will it be possible for you to do such a thing.
0 Kudos
Reply