簡體   English   中英

嘗試使用std :: round()時,我應該添加少量嗎?

[英]Should I add a tiny amount when trying to use std::round()?

在這種情況下,當我們期望四舍五入時, round_to_2_digits()函數會四舍五入。 事實證明,數字不能精確地以雙精度表示。 我不記得確切的值,而是這樣說:

double value = 1.155;
double value_rounded = round_to_2_digits( value );

value是函數的輸出,而不是像上面的代碼那樣精確地為1.155,它實際上返回的是類似1.15499999999999999的值。 因此,在其上調用std::round()將導致1.15而不是我們認為的1.16。

問題:

我認為在調用std::round()之前在round_to_2_digits()添加一個很小的值可能是明智的。

  • 這是標准做法,還是可以接受的? 例如,對要取整的值加上0.0005。
  • 這種“軟糖因子”是否有數學術語?
    • 編輯: “ epsilon”是我正在尋找的術語。
  • 並且由於函數舍入到小數點后僅兩位數,我應該加0.001嗎? 0.005? 0.0005?

舍入函數非常簡單:

double round_to_2_decimals( double value )
{
    value *= 100.0;
    value = std::round(value);
    value /= 100.0;
    return value;
}

第一步是承認double可能不是您應用程序的正確數據類型。 :-)考慮使用定點類型,或將所有值乘以100(或1000,或其他任何值),然后使用整數值。

您實際上不能保證在任何其他情況下添加任何特定的小epsilon不會給您錯誤的結果。 如果您的值實際上 1.54999999 ...,然后將其取整怎么辦? 否則,您將獲得錯誤的價值。

建議的解決方案的問題在於,在解決方案的最后,您仍然會有一個二進制分數,該分數不一定等於您要表示的十進制值。 解決此問題的唯一方法是使用可以精確表示您要使用的值的表示形式。

這個問題沒有多大意義。 POSIX要求std::round從零開始std::round一半。 因此,結果實際上應該是116而不是115 為了實際復制您的行為,我必須使用一個關注舍入模式的函數:

std::fesetround(FE_DOWNWARD);
std::cout << std::setprecision(20) << std::rint(1.155 * 100.0);

這已在GCC 5.2.0和Clang 3.7.0上進行了測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM