繁体   English   中英

C ++ 32位与64位浮动限制

[英]C++ 32bit vs 64bit floating limit

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

  • 为什么64bit中long double的最大值小于32bit?
  • 为什么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的“错误”。

LDBL_MAX =1.132619801677474e-317听起来像某个地方的错误。 标准的要求是,每个可表示为double值也可以表示为long double ,因此LDBL_MAX < DBL_MAX 鉴于您没有展示您的真实测试代码,我个人会在指责编译器之前检查它。

如果两者之间的long double精确存在(非bug)差异,则该差异的基础将是您的32位编译器使用旧的x87浮点运算,其具有80位精度,因此允许一个80位long double

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

它可能比这更复杂。 例如,并非所有x86编译器都必须具有80位long double 他们如何做出决定取决于各种事情,可能包括SSE2具有64位浮点运算的事实。 但可能性是long double大小与double相同,或者更大。

为什么64位版本无法扩展32位版本的数字以填充“40”精度输出?

双精度只有大约15个十进制数字的精度。 超出该数字的数字有时会提供信息,但通常会产生误导。

我不记得关于setprecision的标准是什么,但假设允许实现绘制一条停止生成数字的行, double的精度是绘制它的合理位置。 至于为什么一个实现决定实际做到而另一个没有 - 我不知道。 由于它们是不同的发行版,因此它们可能使用完全不同的标准库。

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

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

有人说过:

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

3.9.1基本类型

  1. 有三种浮点类型:float,double和long double。 double类型提供至少与float一样多的精度,long double类型提供至少与double一样多的精度。 float类型的值集是double类型的值集的子集; double类型的值集是long double类型的值集的子集。 浮点类型的值表示是实现定义的。 积分和浮动类型统称为算术类型。 标准模板numeric_limits(18.2)的特化应指定实现的每种算术类型的最大值和最小值。

另外,不同的CPU对最终结果会产生不同的影响,只要具有更高级别的数字的精度。 编译器也是如此。 VC ++的编译器的行为与borland,GCC / G ++等不同。

暂无
暂无

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

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