views:

336

answers:

5

Hi,on my 32-bit machine (with an Intel T7700 duo core), I have 15 precision digits for both double and long double types for the C language. I compared the parameters LDBL_DIG for long double and DBL_DIG for double and they are both 15. I got these answers using MVS2008. I was wondering if these results can be compiler dependent or do they just depend on my processor?

Thanks a lot...

+1  A: 

It's possible for them to depend on compiler, but in general, they will just depend on architecture. If the compilers are using the same include files, in particular, these will probably not vary. It's a good idea to check them to be sure though, if you want to write portable code.

WhirlWind
Thanks. I will try to lay my hands on another compiler (maybe Borland) and do the test.
yCalleecharan
+1  A: 

Right. These are implementation-dependent. The only guarantees of the C standard are:

  1. float is a subset of double and double is a subset of long double (6.2.5/10)
  2. FLT_RADIX ≥ 2 (5.2.4.2.2/9)
  3. FLT_DIG ≥ 6, DBL_DIG ≥ 10, LDBL_DIG ≥ 10
  4. FLT_MIN_10_EXP, DBL_MIN_10_EXP LDBL_MIN_10_EXP ≤ -37
  5. FLT_MAX_10_EXP, DBL_MAX_10_EXP, LDBL_MAX_10_EXP ≥ +37
  6. FLT_MAX, DBL_MAX, LDBL_MAX ≥ 1e+37 (5.2.4.2.2/10)
  7. FLT_EPSILON ≤ 1e-5, DBL_EPSILON ≤ 1e-9, LDBL_EPSILON ≤ 1e-9 (5.2.4.2.2/11)
  8. FLT_MIN, DBL_MIN, LDBL_MIN ≤ 1e-37

Treating long double = double is permitted by the C standard.

KennyTM
As @Kenny doesn't quite make clear 'A is a subset of B' does not exclude the possibility that 'A==B'
High Performance Mark
Thanks for these useful values. What do the numbers in the brackets represent like (6.2.5/10) on the first line?
yCalleecharan
@yCalleecharan -- until @Kenny comes back, I'd work on the assumption that they are the clauses of the C standard.
High Performance Mark
@yCalleecharan: They're clauses of the C standard.
KennyTM
Ok. Good to know :).
yCalleecharan
+1  A: 

Some compilers support a long double format that has more precision than double. Microsoft MSVC isn't one of them. If 15 significant digits isn't good enough then the odds are very high that you shouldn't be using a floating point type in the first place. Check this thread for arbitrary precision libraries.

Hans Passant
Thanks. I've heard about arbitrary precision. Apfloat is one of such libraries. In numerical computations, one would like much precision especially when the system under consideration is known not to behave well. I was always assuming that it's the processor/architecture of the computer that decides the precision (and this I know now is false).What other compilers that you know support a long double type with more than 15 precision digits?
yCalleecharan
Link: http://en.wikipedia.org/wiki/Quad_precision
Hans Passant
Thanks. The link doesn't mention other C compilers though. Interesting to note that older MVS had 80-bit precision long double data type (http://msdn.microsoft.com/en-us/library/9cx8xs15.aspx).
yCalleecharan
Did you read it? Link: http://en.wikipedia.org/wiki/Quad_precision#Implementations
Hans Passant
Sorry that I read it fast. I now see that GNU C Compiler is one of such compilers. When we speak of arbitrary precision, then it appears that it's something being done in software and not by the hardware of the computer. Am I right? Will a 64-bit machine in "general" can give a better precision for long double than a 32-bit machine? Sorry for my limited knowledge on this matter.
yCalleecharan
There is no hardware support for formats like this, it will be glacially slow compared to "double".
Hans Passant
A: 

You should also be aware that some CPUs' floating point units support multiple levels of precision for intermediate results, and this level can be controlled at runtime. Apps have been affected by things like buggy versions of DirectX libraries selecting a lower level of precision during a library call and forgetting to restore the setting, thus affecting later FP calculations in the caller.

Andrew Medico
Thanks. But (new ?) Intel processors are supposed to better processors at mathematical computations. Am I right? You're mentioning effects of buggy DirectX libraries. Do we as programmers have any control on this?
yCalleecharan
+1  A: 

While the C standard does not require this, it STRONGLY ADVISES that float and double are standard IEEE 754 single and double precision floating-point types, respectively. Which they are on any architecture that supports them in hardware (which means practically everywhere).

Things are slightly more tricky with long double, as not many architectures support floating-point types of higher-than-double precision. The standard requires that long double has at least as much range and precision as double. Which means that if an architecture does not support anything more, long double type is identical to double. And even if it does (like x87), some compilers still make long double equivalent to double (like M$VC), while others expose the extended precision type as long double (like Borland and GCC).

Even if the compiler exposes the extended precision type, there is still no standard on what exactly "extended-precision" means. On x87 this is 80-bit. Some other architectures have 128-bit quad-precision types. Even on x87 some compilers have sizeof(long double) = 10, while others pad it for alignment, so that it is 12 or 16 (of 8 if long double is double).

So the bottom line is, implementation of long double varies across platforms. The only thing you can be sure about it, is that it is at least equivalent to double. If you want to write portable code, don't depend on its representation - keep it away from interfaces and binary I/O. Using long double in internal calculations of your program is OK though.

slacker
Thanks for the useful information. I shall try with Borland and see if I get any difference from MVS2008.
yCalleecharan