开发者

C precision of double: compiler dependent?

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...


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.


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.


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜