2017-10-15 93 views
0

我試圖在num中打印2個小數點的Cpp平均值。 avgfloatsumfloat,countint舍入到小數點後第二位,除非數字是整數C++

目前如果我有10/1例如輸出10.00。我想輸出只是10.如果avg得到值3.1467665例如,它應該顯示爲3.14

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

舍入應該只是輸出。無需更改avg,但如果它更容易,其值可以更改。

在C++之前尋找一種使用標準的解決方案11。

UPD:當我希望它是27.5時,輸出是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.14 3.1421783921,而不是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

如果有一種方法可以使用舊的標準(在c11之前)來重寫,它會很棒。無論如何,我會接受這個答案。非常感謝你。 –

+1

你可以用一個簡單的整數轉換替換昂貴的'modf'調用,例如'auto precision =(int(avg)!= avg)? ...:...;',給出'avg'支持的值範圍,選擇合適的整數類型。 – IInspectable

+0

那麼當我希望它是27.5時,輸出是27.50。有沒有辦法做到這一點? –

相關問題