2

So I know setprecision(int n) should be used when printing a double value with precision n. However, I've run into a problem on a project that I'm working on that is akin to this code:

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    double var = 1.0000001;
    cout << setprecision(10)<< var << endl;
    string str = to_string(var);
    cout << str << endl;
    return 0;
}

Here is the output:

1.0000001
1.000000

In the project I'm working on, I need to save the double value as a string, and it will occasionally need more than six decimal places of precision. Here, precision is clearly lost in the conversion. Any pointers would be greatly appreciated.

user3154754
  • 35
  • 1
  • 7
  • 1
    Possible duplicate of [The precision of std::to\_string(double)](http://stackoverflow.com/questions/14520309/the-precision-of-stdto-stringdouble) – Barmar Mar 03 '16 at 00:42
  • 2
    Use a `stringstream` instead of `to_string` so you can use the formatting options. – Barmar Mar 03 '16 at 00:42
  • Two pointers: 1) `int *p`, 2) don't use `std::to_string` if you need to manage precision. – AnT stands with Russia Mar 03 '16 at 01:04
  • To save the full precision of a `double`, you need more than 10 digits. The 1990 revision of C language provides a constant (`#include ` or `` called `DBL_DIG` which is almost what we want: it gives the maximum number of digits in a decimal number that the `double` type can preserve. C99 added another one: `DECIMAL_DIG`. That one tells us the maximum number of decimal digits we need to exactly preserve the largest floating point type in text. C11 adds `DBL_DECIMAL_DIG`. – Kaz Mar 03 '16 at 01:09
  • For a 64 bit IEEE 754 double, we need 17 decimal digits to preserve the value. – Kaz Mar 03 '16 at 01:13
  • Ha, I found that exact value by messing around with the levels of precision. Thanks for the input. – user3154754 Mar 03 '16 at 02:33

3 Answers3

4

You can use std::stringstream.

#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;

int main(void) {
    double var = 1.0000001;
    cout << setprecision(10)<< var << endl;
    stringstream ss;
    ss << setprecision(10) << var;
    string str;
    ss >> str;
    cout << str << endl;
    return 0;
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
2

If you want to get the full precision of your double without limiting it to a specific value (implied by your "occasionally need more than six decimal places"), and if you are using the Boost libraries, you can also try this following alternative:

#include <boost/lexical_cast.hpp>    
#include <iostream>

using namespace boost;
using namespace std;    

int main() {
    double var = 1.0000001;   
    cout << lexical_cast<string>(var) << endl;
    return 0;
}

This has proven useful in one of my applications where precision did matter, and where the std::stringstream approach was not very convenient and elegant due to usage of some specific logging function wrappers. You can find more information about boost::lexical_cast and how it deals with internal representations here.

Obviously, if you are not currently using Boost in your project, this approach is overkill.

Pyves
  • 6,333
  • 7
  • 41
  • 59
0

try this:

#include <sstream>
#include <string>

// In some function:
double d = 453.23;
std::ostringstream os;
os << d;
std::string str = os.str();
abrahamhs
  • 101
  • 1
  • 4