In this case, you can't prevent it. double
is not capable of precisely representing the value 2.11099999999999999999, and none of the values it can represent distinguishes 2.11099999999999999999 from 2.111.
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html should tell you what you need to know, and possibly more.
If you use a different example, where double
can represent values that distinguish between the rounded and unrounded value, then you could do this:
#include <iostream>
#include <sstream>
#include <iomanip>
int main() {
std::istringstream iss("2.1109999");
double d;
iss >> d;
std::cout << d << "\n";
std::cout << std::setprecision(10) << d << "\n";
}
Output:
2.111
2.1109999
You should be aware, though, that the value stored in d
is not exactly 2.1109999
:
std::cout << std::setprecision(20) << d << "\n";
Output (on my machine, yours may differ because some runtime libraries don't print to 20 s.f at all):
2.1109998999999999292
That's because double
stores values in binary, not decimal. So it can only represent terminating binary fractions. 2.1109999 is not a terminating binary fraction for basically the same reason that one third is not a terminating decimal fraction.
So, there are two ways to keep the given input as-is (i.e. to represent that number precisely):
- don't convert to
double
, leave it as a string. - don't convert to
double
, instead find or write a library that represents decimal fractions and/or rational numbers. For example, the GMP library hasmpq_t
or there's Boost.Rational.