簡體   English   中英

C ++將精度設置為雙精度(不用於輸出)

[英]C++ set precision of a double (not for output)

好吧,所以我試圖以給定的數字精度(不包括小數點之前和之后的總位數,或不包括小數的位數)從雙精度中截斷實際值,而不僅僅是輸出它們,而不僅僅是四舍五入。 我為此找到的唯一內置函數會截斷所有小數,或舍入到給定的十進制精度。 我在網上找到的其他解決方案,只有在您知道小數點前的位數或整數時才能使用。 此解決方案應具有足夠的動態性以處理任意數量的數據。 我整理了一些實現下面這些技巧的代碼,但是我不能動搖有更好的方法來做。 有人知道更優雅的東西嗎? 也許是我不知道的內置函數?

我應該提到原因。 有3種不同的觀測值來源。 所有這三個來源在精度上都達到了一定水平。 如下所示,他們都同意10位數以內。 4659.96751751236 4659.96751721355 4659.96751764253但是我只需要從1個來源中提取即可。 因此,最好的方法是僅使用所有三個源都同意的精度。 所以它不像我在操縱數字,然后需要截斷精度,它們是觀測值。 期望的結果是4659.967517

雙截號(雙數字,整數){

// check valid digits
if (digits < 0)
    return num;

// create string stream for full precision (string conversion rounds at 10)
ostringstream numO;

// read in number to stream, at 17+ precision things get wonky
numO << setprecision(16) << num;

// convert to string, for character manipulation
string numS = numO.str();

// check if we have a decimal
int decimalIndex = numS.find('.');

// if we have a decimal, erase it for now, logging its position
if(decimalIndex != -1)
    numS.erase(decimalIndex, 1);

// make sure our target precision is not higher than current precision
digits = min((int)numS.size(), digits);

// replace unwanted precision with zeroes
numS.replace(digits, numS.size() - digits, numS.size() - digits, '0');

// if we had a decimal, add it back
if (decimalIndex != -1)
    numS.insert(numS.begin() + decimalIndex, '.');

return atof(numS.c_str());

}

因為double精度數不是十進制類型,所以它將永遠無法工作。 截斷您認為一定數量的十進制數字只會在末尾引入一組新的笑話數字。 它甚至可能是有害的:例如0.125是精確的double ,但0.120.13都不是。

如果要使用小數,請使用小數類型或大整數類型,並且約定其中一部分包含小數部分。

我不同意“因此,最好的方法是僅使用所有三個來源都同意的精度”。

如果這些是對物理量的不同度量,或者由於不同的計算方式而導致四舍五入誤差,那么通過取其均值,而不是將它們不同意的數字強制為任意值,您將更好地估計真實值,包括零。

取均值的最終理由是中央極限定理 ,它建議將您的測量值視為正態分布的樣本。 如果是這樣,則樣本均值是總體均值的最佳可用估計值。 您的截斷過程會低估實際值。

通常最好保留計算過程中掌握的每條信息,然后記住輸出結果時精度有限。

除了給出更好的估計之外,取三個數字的平均值也是一個非常簡單的計算。

暫無
暫無

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

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