2011-11-20 76 views
0

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

有没有办法,我可以设置精度矢量到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())); 
     } 
+3

*“但是在矢量v中是”0.079999998“”* - 你怎么知道? –

+0

在调试时查看矢量。 – Lexicon

回答

1

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

你有几个选择:

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

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

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

+0

我需要将向量中的值设为.08,因为我需要将该值作为.08而不是.07998进行操作。例如,我需要通过.001减去每个值,然后乘以2. – Lexicon

+0

@Lexicon:再次阅读我的最后一段。普通浮点数*不能取值0.08,就像普通整数不能取值1/3。 –