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"

即使我没有告诉它对(如作为参数传递给函数)进行四舍五入,如何std::stringstream知道它8999900必须恢复为一个?但不要为高于 12 的参数执行此操作9812setprecision

4

1 回答 1

1

将二进制浮点格式化为十进制值是相当棘手的。潜在的问题是二进制浮点不能准确地表示十进制值。即使是像 0.1 这样的简单数字也无法使用二进制浮点数精确表示。即表示的实际值略有不同。当使用聪明的算法进行读取(“Bellerophon”)和格式化(“Dragon4”;这些是原始论文中的名称并且在实践中使用的两种算法都有改进)时,浮点数用于传输十进制值。然而,当要求算法格式化比它实际可以容纳的更多的十进制数字时,即超过std::numeric_limits<T>::digits10,它会很乐意这样做,[部分地]显示它实际存储的值。

格式化算法(“Dragon4”)假定给定的值是最接近浮点类型可表示的原始值的值。它使用此信息以及当前位置的误差估计来确定正确的数字。该算法本身并不简单,我还没有完全理解它是如何工作的。Guy L. Steele Jr. 和 Jon L. White 在论文“如何准确地打印浮点数”中对此进行了描述。

于 2012-10-27T23:21:55.630 回答