2012-10-27 40 views
2
double value = 02369.000133699;//acutally stored as 2369.000133698999900 
const std::uint32_t left = std::uint32_t(std::abs(value) < 1 ? 1: (1 + std::log10(std::abs(value)))); 

std::ostringstream out; 
out << std::setprecision(std::numeric_limits<T>::digits10 - left) << std::fixed << value; 
std::string str = out.str(); //str = "2369.00013369900" 

std::ostringstream out2; 
out2 << std::setprecision(std::numeric_limits<T>::digits10) << std::fixed << value; 
std::string str2 = out2.str(); // str2 = "2369.000133698999900" 

我想知道如何std :: stringstream /精度工作格式化浮點數。 看來,如果precision參數優於非小數位數16負數,這導致表單的格式"2369.000133698999900",而不是一個「好」 "2369.00013369900"stringstream setprecision和浮點格式化

如何std::stringstream知道8999900必須恢復到一個9連如果我不「T告訴它做的舍入8(如通過12作爲參數傳遞給setprecision功能)?但沒有爲參數優於這樣做是爲了12

回答

1

格式的二進制浮點十進制值是相當棘手的問題。根本問題是二進制浮點不能表示精確的十進制值伊利。即使像0.1這樣的簡單數字也不能完全用二進制浮點表示。也就是說,表示的實際值稍有不同。當使用聰明的算法進行讀取(「Bellerophon」)和格式化(「Dragon4」;這些是來自原始論文的名稱,並且在實踐中對這兩種算法都有改進)使用浮點數來傳輸十進制值。然而,當要求算法對更多小數位數進行格式化時,它可能實際上保留的數目比大於std::numeric_limits<T>::digits10,它會樂於這樣做,[部分]揭示其實際存儲的值。

格式化算法(「Dragon4」)假定它給出的值是最接近浮點類型可表示的原始值。它使用這些信息和當前位置的誤差估計來確定正確的數字。算法本身並不平凡,我還沒有完全理解它是如何工作的。它在Guy L. Steele Jr.和Jon L. White的論文「如何準確地打印浮點數」中有介紹。