Given the following code :
istringstream i("2.11099999999999999999");
double d;
if (!(i >> d)) {d = 0;}
cout << d << endl;
The output is 2.111 .
I want to have the ability of working with long numbers , float numbers (floating point included) , however when I convert my istringstream to double , I get a rounded number .
How can I prevent that ? How can I keep the given input as-is ?
Regards
In this case, you can’t prevent it.
doubleis 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
doublecan represent values that distinguish between the rounded and unrounded value, then you could do this:Output:
You should be aware, though, that the value stored in
dis not exactly2.1109999:Output (on my machine, yours may differ because some runtime libraries don’t print to 20 s.f at all):
That’s because
doublestores 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):
double, leave it as a string.double, instead find or write a library that represents decimal fractions and/or rational numbers. For example, the GMP library hasmpq_tor there’s Boost.Rational.