字符串流设置精度和浮点格式

stringstream setprecision and floating point formatting

本文关键字:格式 精度 设置 字符串      更新时间:2023-10-16
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必须恢复为一个9,即使我没有告诉它对8进行舍入(就像将12作为参数传递给setprecision函数一样)?但不要对高于12 的参数进行舍入

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

格式化算法("Dragon4")假设它给出的值是最接近浮点类型的原始表示值。它将这些信息与当前位置的误差估计一起使用,以确定正确的数字。算法本身并不平凡,我还没有完全理解它是如何工作的。Guy L.Steele Jr.和Jon L.White的论文《如何准确打印浮点数》中描述了这一点。