2017-10-15 7 views
0

floatの小数点以下2桁までCppの平均値を印刷しようとしています。 avgfloat,sumfloat,countintである。数値が全体でない限り小数点第2位に丸めます

現在、私が10/1を持っていると、たとえば10.00を出力します。例えば、avgの値が3.1467665の場合、出力は3.14と表示されます。

avg = sum/count; 
std::cout << std::fixed << std::setprecision(2) << avg; 

出力は単なる丸めでなければなりません。 avgを変更する必要はありませんが、それが簡単な場合は、その値を変更することができます。

C++ 11より前の標準を使用して解決策を探しています。

UPD:出力を27.50にすると27.50になります。

+0

更新は*かなり*質問を変更します。もはや「丸め」*を求めるのではなく、むしろ「切り捨て」*を求めています。確かに、それは丸め(ゼロまたは無限大のいずれかに向かって)としてカウントされますが、「丸め」*という用語が孤立して見えるときに一般に期待されるものではありません。修正:質問を変更したのは更新プログラムではありませんでした。切り詰めの必要条件は最初からありました。提案された答えはそれに対処しません。 '3.1467665'に対して実行すると、' 3.15'が生成されます。 – IInspectable

答えて

3

avg値の浮動係数に従って精度を選択できます。以下の作品:

int main() { 
    double sum = 10; 
    double count = 3; 
    double avg = sum/count; 
    double mod; 
    std::cout << std::fixed 
      << std::setprecision((modf(avg, &mod) != 0.0) ? 2 : 0) 
      << avg 
      << std::endl; 
} 

追加の仕様を考慮すると:

  • は2.5の代わりに、2.50
  • 3.1421783921のための3.14を書くのではなく、ここでは3.15

が使用可能な実装であるを書きます@ IInspectableの推奨方法:

std::stringstream ss; 
    ss << std::fixed << avg; 

    size_t pos = ss.str().find('.'); 
    if (pos + 2 < ss.str().size()) // If there is a '.' and more than 2 digits after it 
    pos += 3; 
    std::string s = ss.str().substr(0, pos); // Leave only two digits 

    s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return ch != '0'; }).base(), s.end()); // Remove trailing zeros 
    s.erase(std::find_if(s.rbegin(), s.rend(), [](int ch) { return ch != '.'; }).base(), s.end()); // Remove trailing '.' when needed 
    std::cout << s << std::endl; 

この意志出力:

  • 10/4 -> 2.5
  • 10/3 -> 3.33
  • 10/2 -> 5
  • 10/7 -> 1.42
  • 3.9999 -> 3.99
+0

古いstandart(c11より前)を使用してこれを書き換える方法があれば、それは素晴らしいでしょう。とにかく、私はこれを答えとして受け入れます。どうもありがとうございました。 –

+1

高価な 'modf'呼び出しを、単純な整数変換で置き換えることができます。 'auto precision =(int(avg)!= avg)? ...:...; '、' avg'のサポートされている値の範囲で適切な整数型を選びます。 – IInspectable

+0

私はそれを27.5にしたいとき、出力は27.50です。これもやるべき方法はありますか? –

関連する問題