【问题标题】:Set precision of a double variable in 'string to double' using lexical cast使用词法转换设置'string to double'中双精度变量的精度
【发布时间】:2018-06-25 11:48:59
【问题描述】:

我有一个值为 "496934.079" 的字符串。 我使用 boost::lexical_cast () 将其转换为双变量(名为 pVar)。

但是转换后存储在 pVar 中的值是 "496934" 而不是 "496934.079"。小数点后的数字缺失。我已经阅读了关于 std::setprecision() 在输出窗口here 中写入所需精度的双精度值。但它只显示给定精度的值,并没有将它保存在给定精度的变量中。

但我想将双精度值完全存储在字符串变量 str 中,以便 pVar 中的值是 "496934.079"。如何以与输入字符串相同的精度将值存储在变量中,以便可以使用该变量进行进一步处理?

我的代码 sn-p 是:

int func()
{
    string str = "496934.079";
    double pVar = boost::lexical_cast<double> (str);
    cout << pVar << endl;
    return 0;
}

编辑:这种从字符串到浮点的转换是我正在开发的代码的一部分,它逐行解析文本文件中的值并将它们写入另一个文件(.pcd 格式)。我正在添加我用于此转换的整个代码以供参考。

int txt2pcd()
{
    ifstream is("input_text_file.txt");                                         //read input text file
    string str;
    using namespace boost::algorithm;
    pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);
    while(getline(is, str))                                                     //parsing the text file contents line-by-line
    {   
        std::string s = str.c_str();
        std::vector<std::string> result;            
        std::istringstream iss(s);
        for(std::string s; iss >> s; )
            result.push_back(s);

        pcl::PointXYZ point;

        point.x = boost::lexical_cast<double> (result[0]);                      //string to float conversion for adding the X coordinate of the point
        point.y = boost::lexical_cast<double> (result[1]);                      //string to float conversion for adding the Y coordinate of the point
        point.z = boost::lexical_cast<double> (result[2]);                      //string to float conversion for adding the Z coordinate of the point

        point_cloud_ptr->points.push_back (point);
        point_cloud_ptr->width = (int) point_cloud_ptr->points.size ();
        point_cloud_ptr->height = 1;            
    }   
    pcl::io::savePCDFile ("output_pcd_file.pcd", *point_cloud_ptr, false);    //this is where the converted float values are stored (with digits altered after decimal point when compared to text file)
    return 0;
}

以下是文本文件中的几行示例以及转换后的“.pcd”文件中的相应行。

在文本文件中:

496934.999 5419547.239 265.179

496933.981 5419542.579 263.819

496934.891 5419545.399 264.849

496934.939 5419546.329 265.111

496934.829 5419544.489 264.781

在 '.pcd' 文件中(对应的值由 boost::lexical_cast () 产生)

496935 5419547 265.17899

496933.97 5419542.5 263.819

496934.91 5419545.5 264.849

496934.94 5419546.5 265.11099

496934.84 5419544.5 264.78101

请注意,这些值要么四舍五入,要么在输出“.pcd”文件中更改小数点后的数字。这可能是什么原因?

【问题讨论】:

  • 事实上,boost::loxical_cast 不是这里的原因:coliru.stacked-crooked.com/a/e47d7cf3fa270efb
  • 值得一提的是std::setprecision 确实不会以任何方式提高/修改double 值的精度。这是标准输出流的绘制工作。该值保持不变。
  • 你如何确定存储在变量中的值?您的 sn-p 以默认精度打印,即六位有效数字。 (请注意,最接近的 IEEE 754 双精度为 496934.079000000027008354663849,所以这是您应该得到的值。)
  • @molbdnilo 我正在开发一个程序,它逐行解析文本文件中的值并将它们存储为对应于相对于原点的 3D 点的 XYZ 坐标值(以浮点/双精度格式) .当我验证创建的点的坐标时,我发现它们的 XYZ 值中缺少小数点后的数字。
  • @Ron 是的,我猜到了。即使使用 stod() 我也得到了相同的结果。我想不出一种方法来存储字符串 str 中的值。有可能吗?

标签: c++ precision point-cloud-library boost-lexicalcast


【解决方案1】:

boost::lexical_cast&lt;double&gt;(str) 已将完整值 496934.079 作为 double 返回。此完整值存储在pVar 中,可用于进一步处理。

string str = "496934.079";
double pVar = boost::lexical_cast<double>(str); // pVar now contains 496934.079

std::setprecision 不会影响存储的值 - 它只是设置显示的位数(小数点之前和之后)。默认显示精度为6,所以:

std::cout << pVar << std::endl; // this prints "496934" (6 digits)

以更高的精度显示存储的值(例如10)给出:

#include <iomanip>

std::cout << std::setprecision(10) << pVar << std::endl; // this prints "496934.079"

但要重新迭代:这些都不会影响存储的值。 pVar 仍然包含 496934.079。例如:

std::cout << (int) (pVar * 1000) << std::endl; // this displays 496934079

编辑

问题中的更新代码表明,实际上,float 用于存储值,而不是double(参考pcl::PointXYZ)。

float 没有足够的精度来存储完整的值 496934.079 - 相反,它将存储它可以表示的最佳近似值 (496934.09375)(参考例如 What is the difference between float and double?)。

如果您想确保可以保留完整值(未修改),请务必坚持使用double

【讨论】:

  • 此答案与问题不符。 cout 的用法似乎只是为了说明; OP 正在使用boost::lexical_cast 并专门询问了这一点。您必须显示替代品(例如stringstream.str())。
  • @LightnessRacesinOrbit :我以不同的方式阅读了这个问题。我很清楚,OP 将显示的内容 (496934) 与 lexical_cast 存储在 dbl 中的内容混淆了。我的回答表明lexical_cast 确实存储了完整值(496934.079)。此外,OP 误解了精度的含义(通过他使用 3 来尝试获取小数点后的 3 位)。我的回答试图消除这种误解。
  • @SanderDeDycker 感谢您的回复。正如轨道中的 Lightness Races 所提到的,以适当的精度打印值不是这里的问题。我已经编辑了这个问题。我发现存储的值不是我在字符串中传递的值。存储值中完全缺少小数点后的位数。
  • @Sjs :您更新的代码使用float,而不是double(参考pcl::PointXYZ)。 float 没有存储您想要存储在其中的完整值的精度。参考。例如。 stackoverflow.com/questions/5098558/float-vs-double-precision
  • @Sjs :我不知道点云库在这方面提供了什么。这还取决于您要寻找的精度。 float 得到 7-8 位数,double 得到 15-16。除此之外,存在提供任意精度数值类型的库,或者您可以选择定点数据类型。但首先,请确保您确实需要额外的精度。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-05
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
相关资源
最近更新 更多