C ++使用stringstream进行双转换的字符串会产生精度错误

时间:2015-12-18 12:12:34

标签: c++ visual-c++ precision

这是我的代码片段。我需要一些帮助来消除下面显示的错误。

#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;
}

这给出了输出:

5.200000000002
0

如何删除此精度错误?我可以使用std :: setprecision()来解决问题吗?

2 个答案:

答案 0 :(得分:3)

numeric_limits<double>::digits10可用于查找double唯一可表示的位数。

我看到你用Visual Studio标记了你的问题。您可以在http://webcompiler.cloudapp.net/上测试此代码,以获取Visual Studio的double唯一可表示数字的数字:

#include <iostream>
#include <limits>

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

此代码输出2将输出:

  

15

这意味着任何double最多14个小数位stringstream的往返中幸存并且仍然等于它自己。

上述意味着您的示例中没有包含导致往返失败的内容,或者您​​使用的是非IEEE标准的非标准源文件。 (例如,我可以执行live example on gcc向您提供相反的输出,并且在Visual Studio上运行相同的代码与您的输出不一致。)

无论哪种方式,对于任何可唯一表示的double(如5.2),您可以通过设置精度来确保通过stringstream的往返成功。 Precision是一个粘性修改器,所以你只需要在流构造之后设置一次。在您的示例中,您使用stringstream stream,因此在使用stream之前,您需要设置此修饰符:

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

答案 1 :(得分:0)

您可以像这样使用它,以便以正确的方式显示双号:

{{1}}

http://cpp.sh/9lub

关于比较您可以查看此What is the most effective way for float and double comparison?

的浮点数