2011-08-20 61 views
0

可能重複初始化它:
Floating point inaccuracy examples龍雙不打印爲常數我

林有一個問題...當我編譯SRC,變量顯示ISN 「T相同,我初始化,看到它:

#include <iostream> 

    using namespace std; 

    int main() 
    { 
     long double mynum = 4.7; 
     cout.setf(ios::fixed,ios::floatfield); 
     cout.precision(20); 
     cout << mynum << endl; 
    } 

然後:

[[email protected] ~]$ ./a.out 
4.70000000000000017764 

如何解決?我想「COUT」顯示4.700000 ......

+8

...再次。 –

+0

這個問題有六百萬億投資。搜索「浮點不精確」。 – Puppy

+1

「長雙倍比我的字面常量更精確」的角度並不是在600萬億次的所有困境中都存在。 –

回答

5

您的變量是long double,但文字4.7的默認精度僅爲double。由於您將其打印爲long double,因此解釋會選擇使用足夠的有效數字來打印它,以將其與相鄰的long double值區分開,即使這些相鄰值不可能是double s。

+1

有斑點,使用正確的文字可以獲得預期的19位精度! –

2

大多數平臺,包括你,可以只有代表這些人恰恰是浮點數其中有一個短暫的,有限的二進制展開,即它們是兩個大國的有限資金。 4.7是不是這樣的一個數字,所以它不能被你的平臺上準確地表示,如果你要求過多的精度(20是你的尾數64位,log_10(64)爲19.27太多了),那麼你將不可避免地面臨小錯誤。 (但是,正如@Henning所說,當你從一個(非long)double中分配時,你已經失去了精度;你應該把你的字面常量寫成一個long double:4.7L然後你應該只看到一個錯誤第二位)

1

某些數字不能用二進制表示。顯然,4.7是其中之一。你看到的是最接近4.7的數字。

除了將精度設置爲較低的數字之外,您無能爲力。

2

float S和double s爲二進制浮點類型,即它們存儲尾數和在鹼的指數2.

這意味着,不能被精確表示成尾數的有限位數任何十進制數將近似;您顯示的問題來自於此:4.7不能完全代表double的尾數(文字4.7的類型爲double,讚譽@Henning Makholm用於發現它),因此使用最接近的近似值。

爲了更好地可視化的問題:在基體3,是2/3具有有限表示的數量(即0.2 ),而在基座10它是一個週期性的數目(0,6666666 ...);如果您只有有限的數字空間,則必須執行一個近似值,即0,66666667。這裏完全一樣,源代碼爲10,「目標」基數爲2.

如果有特殊需要避免這種近似值(例如,在處理小數金額時)特殊decimal類型可以被使用,該商店尾數和指數在基座10(C++不提供這種類型其自己的,但也有許多可用decimal類的淨);仍然,對於「正常」/科學計算,使用二元FP類型,因爲它們更快,更節省空間。

2

雙打的內部表示不允許「精確」表示4.7。 「最接近的」是4.70000000000000017764。實際上,當你有64位雙打時,不需要看20的精度。最大有效精度約爲15.嘗試使用12左右,

cout.precision(12); 

你應該得到你想看到的。