简体   繁体   English

C的精度为double:编译器依赖?

[英]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. 在我的32位机器上(带有Intel T7700双核),我有15个精确数字,用于C语言的双重和双重类型。 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. 我比较了LDBL_DIG用于long double和DBL_DIG用于double,它们都是15.我使用MVS2008得到了这些答案。 I was wondering if these results can be compiler dependent or do they just depend on my processor? 我想知道这些结果是否可以依赖于编译器,还是只依赖于我的处理器?

Thanks a lot... 非常感谢...

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: C标准的唯一保证是:

  1. float is a subset of double and double is a subset of long double (6.2.5/10) float的一个子集doubledouble的一个子集long double (6.2.5 / 10)
  2. FLT_RADIX ≥ 2 (5.2.4.2.2/9) 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) 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) 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. C标准允许处理long double = double

Some compilers support a long double format that has more precision than double. 一些编译器支持长双精度格式,其精度高于双精度。 Microsoft MSVC isn't one of them. Microsoft MSVC不是其中之一。 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. 如果15位有效数字不够好,那么首先你不应该使用浮点类型的几率非常高。 Check this thread for arbitrary precision libraries. 检查此线程是否有任意精度库。

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. 虽然C标准不要求这样做,但强烈建议floatdouble分别是标准IEEE 754单精度和双精度浮点类型。 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. 由于没有多少架构支持高于双倍精度的浮点类型,因此使用long double会稍微复杂一些。 The standard requires that long double has at least as much range and precision as double . 该标准要求long double 至少具有double范围和精度。 Which means that if an architecture does not support anything more, long double type is identical to double . 这意味着如果架构不支持更多,则long double类型与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). 即使它确实如此 (如x87),一些编译器仍然会使long double等效于double (如M $ VC),而其他编译器则将扩展精度类型暴露为long double (如Borland和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. 在x87上,这是80位。 Some other architectures have 128-bit quad-precision types. 其他一些架构具有128位四精度类型。 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 ). 甚至上的x87一些编译器具有sizeof(long double) = 10,而其他的垫它用于对准,这样它是12或16(8如果long doubledouble )。

So the bottom line is, implementation of long double varies across platforms. 所以最重要的是, long double实现因平台而异。 The only thing you can be sure about it, is that it is at least equivalent to double . 你唯一可以肯定的是,它至少相当于double If you want to write portable code, don't depend on its representation - keep it away from interfaces and binary I/O. 如果要编写可移植代码,请不要依赖其表示 - 远离接口和二进制I / O. Using long double in internal calculations of your program is OK though. 在程序的内部计算中使用long double是可以的。

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. 您还应该知道某些CPU的浮点单元支持中间结果的多个精度级别,并且可以在运行时控制此级别。 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. 应用程序受到了错误的DirectX库版本的影响,在库调用期间选择较低的精度并忘记恢复设置,从而影响调用者的后续FP计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM