0

我正在逐行读取 CSV 并标记每个逗号分隔值。每个标记都是一个字符串类型。我将它放入浮点类型的向量中。在下面的示例中,例如,如果 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()));
        }
4

2 回答 2

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 为单位测量所有内容),也可以使用十进制浮点数(很少见),或者您可以存储有理数(整数的商)。如果你只做加法和减法,定点将是自然的方法。

于 2011-11-20T22:29:01.507 回答
1

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

你有几个选择:

  1. 正确处理不精确性。在处理浮点数时,您必须始终注意精度,因此如果您想将该数字显示到最接近的 2 位小数,请进行适当的四舍五入,它将始终如您所愿。

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

于 2011-11-20T22:29:16.517 回答