Question

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"

I'm wondering how std::stringstream/precision works for formatting floating-point number. It seems that if precision argument is superior to 16 minus number of non-fractional digits, this lead to a formatting of form "2369.000133698999900" instead of a "nice" "2369.00013369900"

how std::stringstream know that 8999900 must be resume to one 9 even if I don"t tell it to do the rounding on the 8 (like passing 12 as argument to the setprecision function) ?but don't do it for argument superior to 12

Was it helpful?

Solution

Formatting binary floating points as decimal values is fairly tricky. The underlying problem is that binary floating points cannot represent decimal values accurately. Even a simple number like 0.1 cannot be represented exactly using binary floating points. That is, the actual value represented is slightly different. When using clever algorithms for reading ("Bellerophon") and formatting ("Dragon4"; these are the names from the original papers and there are improvements of both algorithms which are used in practice) floating point numbers be used to transport decimal values. However, when asking the algorithm to format more decimal digits than it can actually hold, i.e., more than std::numeric_limits<T>::digits10, it will happily do so, [partially] revealing the value it is actually storing.

The formatting algorithm ("Dragon4") assumes that the value it is given is the value closest to the original representable with the floating point type. It uses this information together with an error estimate for the current position to determine the correct digits. The algorithm itself is non-trivial and I haven't fully understood how it works. It is described in the paper "How to Print Floating-Point Numbers Accurately" by Guy L. Steele Jr. and Jon L. White.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top