C ++ 32位的64位VS浮动限制(C++ 32bit vs 64bit floating lim

2019-09-23 09:48发布

由于代码段如下,我只是想知道

  • 为什么长双的最大值是64位比32位更小?
  • 为什么64位版本不能在32位版本的扩展尽可能多的数字,以填补“40”精密输出?
  • 似乎LDBL_MIN和LDBL_MAX的值相等,则是一个错误?

我特地到我的机器float.h中的文件,但无法找到这些宏观常量的明确定义。

测试代码(平台= Win7-64bit)

#include <cfloat>
#include <iomanip>
cout<<"FLT_MAX   ="<< setprecision(40) << FLT_MAX  << endl;
cout<<"DBL_MAX   ="<< setprecision(40) << DBL_MAX  << endl;
cout<<"LDBL_MAX  ="<< setprecision(40) << LDBL_MAX << endl;
cout<<"FLT_MIN   ="<< setprecision(40) << FLT_MIN  << endl;
cout<<"DBL_MIN   ="<< setprecision(40) << DBL_MIN  << endl;
cout<<"LDBL_MIN  ="<< setprecision(40) << LDBL_MIN << endl;

32位结果(MinGW的-20120426)

FLT_MAX  =340282346638528859811704183484516925440
DBL_MAX  =1.797693134862315708145274237317043567981e+308
LDBL_MAX =1.189731495357231765021263853030970205169e+4932
FLT_MIN  =1.175494350822287507968736537222245677819e-038
DBL_MIN  =2.225073858507201383090232717332404064219e-308
LDBL_MIN =3.362103143112093506262677817321752602598e-4932

64位结果(MinGW64-TDM 4.6)

FLT_MAX  =340282346638528860000000000000000000000
DBL_MAX  =1.7976931348623157e+308
LDBL_MAX =1.132619801677474e-317
FLT_MIN  =1.1754943508222875e-038
DBL_MIN  =2.2250738585072014e-308
LDBL_MIN =1.132619801677474e-317

谢谢。

[编辑]:采用最新MinGW64-TGM 4.7.1中,LDBL_MAX的 “错误”,LDBL_MIN似乎去除。

Answer 1:

LDBL_MAX =1.132619801677474e-317听起来像一个错误的地方。 它是每一个值表示为一个标准的要求double也可以表示为一个long double ,所以它是不允许的LDBL_MAX < DBL_MAX 。 既然你还没有表现出你真正的测试代码,我个人会检查指责编译之前。

如果真的有一个(非错误)的区别long double两者之间,那么这种差异的基础上,将是您的32位编译器使用旧的x87浮点运算,它具有80位精度,因此允许一个80位long double

您的64位编译器64采用了新的64位浮点运算。 没有80位精度,并且它不打扰切换的x87指令来实现更大的long double

有可能更复杂,以它比。 例如并非所有的x86编译器一定有一个80位long double 。 他们是如何作出这样的决定取决于很多方面,可能包括的事实,SSE2具有64位浮点欢声笑语。 但可能是long double的尺寸与同double ,或者说,它是更大的。

为什么64位版本不能在32位版本的扩展尽可能多的数字,以填补“40”精密输出?

双只具有精度约15个十进制数字。 除此之外,数字有时信息,但通常是误导性的。

我不记得是什么标准说,有关setprecision ,但假设实现被允许绘制它停止生成数字的线,精度double是一个合理的地方画出来。 至于为什么一个实现决定真正做到这一点,而另一个没有 - 我不知道。 因为他们是不同的分布,他们可能会使用完全不同的标准库。

同样的“伪精确”就是为什么你看到340282346638528859811704183484516925440在一种情况下为FLT_MAX,但340282346638528860000000000000000000000在其他。 一个编译器(或更确切地说,一个库的实现)已经去的麻烦,计算大量数字。 其他已经放弃了早期和圆润。



Answer 2:

要回答这个问题,我只是做了几个假设:1)您只在64位机2)的编译器(也就是说,他们实际上是妹妹的编译器相同的子版本的不同位版本上测试该)。

话虽如此说:

从“ISO / IEC 14882国际标准第一版1998-09-01”

3.9.1基本类型

  1. 有三种浮点类型:浮动,双,和长双。 类型双提供至少尽可能精确float和类型长双提供至少尽可能精确的两倍。 该组型浮子的值是该组中的类型的双值的子集; 该集合中的类型的双值的是该组中的长型的双值的一个子集。 浮点类型的值表示是实现定义的。 整型和浮点型,统称算术类型。 标准模板numeric_limits(18.2)的特应的实现指定每个运算类型的最大和最小值。

另外不同的CPU都会对最终的结果有不同的影响,只要有更高层次的数字精度。 也是一样的编译器。 VC ++的编译器不会表现相同的Borland,也不GCC / G ++,等。



文章来源: C++ 32bit vs 64bit floating limit