Установить точность при push_back на Vector
Я читаю из 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 ответа
Ты используешь atof
, что подразумевает, что вы используете float
держать данные. Значения с плавающей точкой не содержат значения base-10 так точно, как вы могли бы ожидать. Такие простые числа, как это, могут не иметь хорошего двоичного представления.
У вас есть пара вариантов:
Справиться с неточностью правильно. Вы должны всегда помнить о точности при работе с плавающей точкой, поэтому, если вы хотите отобразить это число с точностью до 2 десятичных знаков, выполните правильное округление, и оно всегда будет работать так, как вы хотите.
Используйте только целые числа. Если вам нужно только 2 цифры точности после десятичной точки, просто сохраните значения как
int
которые умножаются на 100. Так0.08
хранится как8
, Напишите свои собственные функции для анализа непосредственно в этот формат.
Это не проблема с поплавком. Вы не можете точно представить 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), либо использовать десятичные числа с плавающей запятой (редко), либо вы можете хранить рациональные числа (коэффициенты целых чисел). Если вы делаете только сложение и вычитание, естественным путем будет фиксированная точка.