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
1}}作为{{1}}函数的参数)?但不要用于优于12的参数
答案 0 :(得分:1)
将二进制浮点格式化为十进制值非常棘手。潜在的问题是二进制浮点不能准确地表示十进制值。即使像0.1这样的简单数字也无法使用二进制浮点精确表示。也就是说,表示的实际值略有不同。当使用聪明的算法进行读取(“Bellerophon”)和格式化(“Dragon4”;这些是原始论文中的名称,并且在实践中使用的两种算法都有改进)时,使用浮点数来传输十进制值。但是,当要求算法格式化多于它实际可以保存的十进制数字时,即超过std::numeric_limits<T>::digits10
时,它会很乐意这样做,[部分]显示它实际存储的值。
格式化算法(“Dragon4”)假定它给出的值是最接近原始浮点类型的值。它使用此信息以及当前位置的误差估计来确定正确的数字。算法本身并不重要,我还没有完全理解它是如何工作的。 Guy L. Steele Jr.和Jon L. White在“如何准确打印浮点数”一文中对此进行了描述。