簡體   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