[英]C++ 32bit vs 64bit floating limit
鑒於代碼段如下,我只想知道
我查看了我的機器中的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基本類型
- 有三種浮點類型: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.