2016-06-21 7 views
0

この関数を使用して、fのdouble型を小数点以下のp桁の文字列に変換しています。doubleを文字列に挿入するときの丸めを避ける

static std::string doubleToString(double f, int p) 
{ 
     std::stringstream ss; 
     ss << std::fixed << std::setprecision(p) << f; 
     std::string s = ss.str();         
     s.erase(s.find_last_not_of('0') + 1, std::string::npos);  
     return (s[s.size()-1] == '.') ? s.substr(0, s.size()-1) : s; 
} 

最後に残っている0が消去されます。たとえば、1.230001.23となります。

入力:

double test1 = 1; 
double test2 = 1.12345678; 
double test3 = 1.123456789010; 

std::cout << doubleToString(test1, 8) << " " << doubleToString(test2, 8) << " " << doubleToString(test3, 8); 

出力:

1 1.12345678 1.12345679

あなたはtest1test2が細かい印刷されて見ることができるように。しかし、test3は8番目の数字の後に丸められます。私はそれを避け、数字の残りの部分を "切り捨て"したいので、doubleToString(1.123456789010, 8)1.12345678を返します。

これを行う最も効果的な方法は何ですか?

doubleToString((test3 - (0.5/(pow(10, 8)))), 8) 

それは透明な溶液ではないですが、あなたが欲しいものを行う必要があります。

+0

あなたは '.'を探して、' <位置の後にすべてをカットしてみませんか? > + 8 '? – GMichael

+1

8桁目の正確な値に依存しているのに浮動小数点型を使用する理由がありますか? –

+0

@GMichael私はこの行で丸めが起こっていると思います: 'ss << std :: fixed << std :: setprecision(p)<< f;'。その前に、私は文字列を持っていないので、 "。"を探すことができます。その後、文字列の長さはすでに 'p'です。 @ワーレンPそう、理由がある。正確で浮動小数点でなければなりません。 – Bobface

答えて

1

関数を少し変更するとその仕事ができます。単純にストリームにいくつかの桁を追加し、変換後に削除してください。バイナリ値が期待している10進値よりわずかに小さいかもしれないので、の一部をに丸めることを許可する必要があります。以下の私のコードでは、文字列の変換を14桁に制限しています。これは、1.0から10.0までのIEEE doubleから期待できる最大値です。これよりも大きな値が予想される場合、小数点以下の正確な桁数が減少するため、アルゴリズムを調整する必要があります。

std::string doubleToString(double f, int p) 
{ 
    std::stringstream ss; 
    int p2 = min(p + 2, 14); 
    ss << std::fixed << std::setprecision(p2) << f; 
    std::string s = ss.str(); 
    size_t point = s.find('.'); 
    if (point != std::string::npos && point + 1 + p < s.size()) 
     s.erase(point + 1 + p); 
    s.erase(s.find_last_not_of('0') + 1, std::string::npos); 
    return (s[s.size()-1] == '.') ? s.substr(0, s.size()-1) : s; 
} 

実際にはhttp://ideone.com/xGoDiHでご覧ください。

1

あなたが試すことができます。

編集: あなたの番号から0.000000005を引くだけで、切り上げられません。関数に関数を追加すると、すべての数値でそれを行うことができます:

static std::string doubleToString(double f, int p) 
{ 
    std::stringstream ss; 
    ss << std::fixed << std::setprecision(p) << (f - (0.5/(pow(10, p)))); 
    std::string s = ss.str();         
    s.erase(s.find_last_not_of('0') + 1, std::string::npos);  
    return (s[s.size()-1] == '.') ? s.substr(0, s.size()-1) : s; 
} 
+0

ありがとうございます、直接関数に統合したい場合は – Bobface

+0

関数内で実行したい場合は編集を参照してください。 – Koern

関連する問題