簡體   English   中英

浮點算術的最佳實踐

[英]Best practices for floating-point arithmetics

我正在對小數點輸入執行加法和減法,精確到小數點后第二位。 我試圖通過乘以100將它們轉換為整數來提高准確度,但卻達到了相反的效果。

請考慮以下代碼和輸出:

double d = 2.01;
int a = (int) (d * 100.0);
cout << a << endl;

輸出是:

200

一勞永逸,關於浮點算術的一些最佳實踐是什么? 首先使用上面代碼的一些變體將double轉換為int ,然后將其轉換回來是否可行?

如果將d*100.0的結果打印到(比方說)20位小數,問題將很快變得明顯:

200.99999999999997

由於那(小得多)小於201,當你轉換為int時它會被截斷為200。

顯而易見的解決方法是強制四舍五入。 至少如果你的輸入都是正數,那么就像在結果中加0.5一樣簡單:

int a = (int)(d*100.0 + 0.5);

如果你可以指望你的編譯器支持它,那么使用標准庫的round會更容易:

long a = lround(d*100.0);

這適用於正數和負數。

使用標准數學庫的舍入函數。 在C ++中,這意味着您必須#include <cmath>並使用-lm編譯。

然后,為您的例子:

double d = 2.01;
long x = lround(d*100);
cout << x << endl; // prints 201, for sure.

這將與“添加.5”技巧相同,但它對正數和負數都能正常工作。

閱讀本文並達成啟示:

每個計算機科學家應該知道的浮點運算

浮點算術被許多人認為是一個深奧的主題。 這是相當令人驚訝的,因為浮點在計算機系統中無處不在。 幾乎每種語言都有浮點數據類型; 從PC到超級計算機的計算機都有浮點加速器; 大多數編譯器都會被要求不時編譯浮點算法; 幾乎每個操作系統都必須響應溢出等浮點異常。 本文提供了一個關於浮點的方面的教程,這些方面對計算機系統的設計者有直接影響。 它首先介紹浮點表示和舍入誤差,繼續討論IEEE浮點標准,最后總結了許多計算機構建器如何更好地支持浮點的例子。

為了得到明確的路由,我會使用floor()和ceil()。

那么,對於以下代碼,

 (int)floor( 2.01*100.)

我明白了:

200

但對於:

(int)ceil(2.01*100.)

我明白了:

201

暫無
暫無

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

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