установить точность при push_back на Vector - PullRequest
0 голосов
/ 21 ноября 2011

Я читаю из 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 ]

6 голосов
/ 21 ноября 2011

Это не проблема с поплавком. Вы не можете точно представить 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 голос
/ 21 ноября 2011

Вы используете atof, что означает, что вы используете float для хранения данных.Значения с плавающей точкой не содержат значения base-10 так точно, как вы могли бы ожидать.Такие простые числа, как это, могут не иметь хорошего двоичного представления.

У вас есть пара вариантов:

  1. Правильно справьтесь с неточностью.Вы всегда должны помнить о точности при работе с плавающей запятой, поэтому, если вы хотите отобразить это число с точностью до 2 десятичных знаков, выполните правильное округление, и оно всегда будет работать так, как вы хотите.

    Используйте только целые числа.Если вам нужно только 2 цифры точности после десятичной точки, просто сохраните значения как int, умноженные на 100. Таким образом, 0.08 сохраняется как 8.Напишите свои собственные функции для анализа непосредственно в этом формате.

...