2011-11-20 83 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。 –