0

CSVから1行ずつ読み取り、カンマ区切りの各値をトークン化します。各トークンは文字列型です。そして私はそれを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()));
        }
4

2 に答える 2

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の単位で測定する)、10進数の浮動小数点数(まれ)を使用するか、有理数(整数の商)を格納することができます。足し算と引き算だけを行う場合は、固定小数点が自然な方法です。

于 2011-11-20T22:29:01.507 に答える
1

を使用しています。これは、データを保持するためにatof使用していることを意味します。float浮動小数点値は、期待するほど正確に基数10の値を保持しません。したがって、このような単純な数値は、適切な2進表現を持たない可能性があります。

いくつかのオプションがあります:

  1. 不正確さに適切に対処します。浮動小数点を処理するときは常に精度に注意する必要があるため、その数値を小数点以下2桁まで表示する場合は、適切な丸めを行うと、常に希望どおりに機能します。

  2. 整数のみを使用してください。小数点以下2桁の精度のみが必要な場合はint、100を掛けた値を格納するだけです。したがって0.08、として格納され8ます。この形式に直接解析する独自の関数を作成します。

于 2011-11-20T22:29:16.517 に答える