在Vector上的push_back时设置精度

时间:2011-11-20 22:20:12

标签: c++ boost vector tokenize atof

我正在逐行读取CSV并标记每个逗号分隔值。每个标记都是字符串类型。我把它放入float类型的向量中。在下面的例子中,例如,如果csv中的值是“0.08”,* beg =“0.08”,但是在向量v中它是“0.079999998”

有没有我可以将向量中的精度设置为3位小数等等。

示例:

string line;
boost::char_separator<char> sep(",");
typedef boost::tokenizer< boost::char_separator<char> > t_tokenizer;
ifstream myfile (fileName);

if(myfile.is_open())
{
    while (myfile.good())
    {
        getline (myfile,line);
        t_tokenizer tok(line, sep);

        for (t_tokenizer::iterator beg = tok.begin(); beg != tok.end(); ++beg)
        {
             string temp = *beg;
             this->v.push_back(::atof(temp.c_str()));
        }

2 个答案:

答案 0 :(得分:6)

浮点数不是问题。你不能完全代表0.8,但不用担心 - 只需输出具有所需精度的值:

#include <iomanip>   // for fixed and setprecision
#include <iostream>  // for cout
#include <cstdio>    // for printf

for (auto it = v.cbegin(), end = v.cend(); it != end; ++it)
{
  std::cout << std::fixed << std::setprecision(3) << *it << std::endl;
}

或者,您可以使用std::printf("%.3f\n", *it)

如果您确实希望在数据结构中存储精确值,则无法使用常规浮点数。你可以使用某种整数的定点解释(例如,以1/1000为单位测量所有内容),或者你可以使用十进制浮点数(罕见),或者你可以存储理性数字(商)整数)。如果你只做加法和减法,定点将是自然的方式。

答案 1 :(得分:1)

您正在使用atof,这意味着您正在使用float来保存数据。浮点值不能像您预期的那样精确保持基数为10的值。这样简单的数字可能没有很好的二进制表示。

您有几个选择:

  1. 妥善处理不精确问题。处理浮点时必须始终注意精度,因此如果要将该数字显示为最接近的2位小数,请进行适当的舍入,它将始终按您的意愿工作。

  2. 仅使用整数。如果您在小数点后只需要2位数的精度,则只需将值存储为int,然后乘以100.因此0.08存储为8。编写自己的函数直接解析为这种格式。