简体   繁体   中英

C++ String to double conversion using stringstream gives precision error

This is a snippet of my code. I need some help in removing the error shown below.

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    char doubleStr[] = "5.2";
    double d = 0.0;
    std::stringstream stream (doubleStr);
    stream >> d;
    std::cout << d << std::endl;
    std::cout << (d <= 5.2);
    return 0;
}

This gives output:

5.200000000002
0

How to remove this precision error? Can I use std::setprecision() to solve the issue?

numeric_limits<double>::digits10 can be used to find the number of digits that are uniquely representable by a double .

I see you've tagged your question with Visual Studio. You can test this code on http://webcompiler.cloudapp.net/ to get Visual Studio's number of uniquely representable digits for a double :

#include <iostream>
#include <limits>

int main() { std::cout << std::numeric_limits<double>::digits10 << std::endl; }

This code will not output 2 it will output:

15

Which means that any double up to 14 decimal places will survive the round trip through a stringstream and still be equal to itself.


The above means that there is something you are not including in your example that is causing the round trip failure, or you are using non-standard source files that are not IEEE compliant. (For example I can do a live example on gcc that gives a contrary output to yours, and running the same code on Visual Studio disagrees with your output.)

Either way, for any uniquely representable double (like 5.2), you can ensure that round trip success through a stringstream by setting the precision. Precision is a sticky modifier, so you'll only need to set it once after stream construction. In your example you use stringstream stream so before you work with stream you'd need to set this modifier:

stream.precision(numeric_limits<double>::digits10 - 1);

You can use it like this in order to show the double number in the right way:

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
#include <limits>
int main()
{
    char doubleStr[] = "5.2";
    double d = 0.0;
    std::stringstream stream (doubleStr);
    stream >> d;
    std::cout << std::setprecision(2)<<  d << std::endl;
    return 0;
}

http://cpp.sh/9lub

about comparing float point numbers you may look at this What is the most effective way for float and double comparison?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM