2012-11-14 77 views
1

我從其中包含以下行的文本文件閱讀:C++ istream提取精度?

 deltaT   0.005; 

一旦我得到了一個字符串中正確的路線,我想讀出這樣的代碼值:

 double deltaT; 
     stringstream ss(line); 
     ss >> tag;    //Contains:   deltaT 
     ss >> deltaT;    //Should contain: 0.005 

在調試過程中,我看到的DeltaT包含:0.0050000000000000001

那麼,有沒有一種方法來設置提取的「精確」像有一個流插入?

或者什麼是保證文本文件中的值是我的程序中的雙精度值的最佳方法。

謝謝, 瑪德琳。

+2

[這可能會告訴你爲什麼你會看到你所看到的。](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)。對於SO Q&A浮點精度的主題,您可能會發現以下[搜索結果](http://stackoverflow.com/search?q=Floating+Point+Precision)也很有趣。 – WhozCraig

回答

2

這就是二進制浮點類型的常見問題:0.005是不是由double精確表示,所以從「十進制文本」轉換產生由double最相似的數字表示的。

有沒有解決辦法,如果你想使用double或其它有限,二進制浮點類型,因爲0.005在小數有限的形式,但is periodic in binary(以及任何FP型的尾數是有限的)。

要了解這是可能的,考慮分數1/3:在基座3它具有有限的表示,而在基座10是週期性:

(1/3) = 0.33333 .. 。 = 0.1

現在,任何「常規」浮點型具有用於尾數(即顯著數字存儲)只有一些有限的空間,所以每一個週期數必須被截斷(實際上四捨五入) 在某一點;這會導致您看到的精度損失。

請注意,有幾個「任意精度庫」可用於處理這類問題,並且僅通過可用內存限制精度(例如GMP),但是您應該考慮是否額外複雜性/性能損失是實際上由精確度的增加來證明是合理的。

另一種解決方案(通常用於計算涉及貨幣的計算)是使用固定精度類型,將數量作爲整數「隱式縮放」一些十進制因子(概念是將美分作爲整數存儲美元爲float或其他);這避免了從小數轉換爲二進制轉換的任何驚喜,因爲所有整數都可以在任何基數中用有限數量的數字完全表示。

0

讀取數值時,不存在對精度的限制。不管怎樣,你都不想這樣做:你想得到最接近的價值。從簡單的看來,這似乎是你得到的!值0.005看起來不像一個可以完全用二進制浮點表示的值。該類型double和它的朋友表示爲(-1)標誌 * 尾數 * 2 指數,這是顯而易見,這並不能代表所有的十進制值。

問題更多與格式:你應該讓格式選擇感覺格式化多少數字。假設原始值是從某個源讀取的,並且是一個十進制值而不是某些計算的結果,那麼在格式化時應該返回原始值(除了尾部零,即,)。