Search code examples
c++boostvectortokenizeatof

set precision when push_back on Vector


I'm reading from a CSV, line by line and tokenizing each comma separated value. each token is a string type. and I'm putting it into a vector of type float. In the example below, if for example if the value in the csv is "0.08" , *beg = "0.08" , but in vector v it is "0.079999998"

Is there someway that I can set the precision in the vector to 3 decimal places or something.

example:

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()));
        }

Solution

  • You are using atof, which implies you're using float to hold the data. Floating point values do not hold base-10 values as accurately as you might expect. So simple numbers like this may not have a good binary representation.

    You have a couple options:

    1. Deal with imprecision properly. You must always be aware of precision when dealing with floating point, so if you want to display that number to the nearest 2 decimal places, do the proper rounding and it will always work like you want.

    2. Use integers only. If you only ever need 2 digits of precision after the decimal point, just store the values as int which are multiplied by 100. So 0.08 is stored as 8. Write your own functions to parse directly into this format.