簡體   English   中英

c ++不正確的浮點運算

[英]c++ incorrect floating point arithmetic

對於以下程序:

#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    for (float a = 1.0; a < 10; a++)
        cout << std::setprecision(30) << 1.0/a << endl;
    return 0;
}

我收到以下輸出:

1
0.5
0.333333333333333314829616256247
0.25
0.200000000000000011102230246252
0.166666666666666657414808128124
0.142857142857142849212692681249
0.125
0.111111111111111104943205418749

對於較低位的數字,這絕對不是正確的,特別是對於1 / 3,1 / 5,1 / 7和1/9。 事情剛開始出錯10 ^ -16我希望看到更多類似的東西:

1
0.5
0.333333333333333333333333333333
0.25
0.2
0.166666666666666666666666666666
0.142857142857142857142857142857
0.125
0.111111111111111111111111111111

這是float類中的繼承缺陷嗎? 有沒有辦法克服這個並進行適當的划分? 是否有用於執行精確十進制運算的特殊數據類型? 在我的例子中,我只是做了一些愚蠢或錯誤的事情嗎?

計算機無法表示很多數字,即使您使用浮點數或雙精度浮點數也是如此。 1/3,或.3重復,是這些數字之一。 所以它只是盡力而為,這就是你得到的結果。

請參閱http://floating-point-gui.de/或google float precision,這里有大量的信息(包括許多SO問題)。

回答你的問題 - 是的,這是float類和double類的固有限制。 一些數學程序(MathCAD,可能是Mathematica)可以進行“符號”數學運算,從而可以計算出“正確”的答案。 在許多情況下,即使在非常復雜的計算中也可以管理舍入誤差,使得前6-8位小數是正確的。 然而,情況恰恰相反 - 可以構建天真的計算,返回非常不正確的答案。

對於像整數除法這樣的小問題,你會獲得相當數量的小數位精度(可能是4-6位)。 如果你使用雙精度浮點數,那么可能會達到8個。如果你需要更多...好吧,我會開始質疑為什么你需要那么多小數位。

首先,由於你的代碼是1.0/a ,它給你double1.0double值, 1.0ffloat )因為C ++(和C)的規則總是將較小的類型擴展為較大的類型,如果操作數為一個操作是不同的大小(因此, int + char在添加值之前將char變為intlong + int將使int長等等)。

第二個浮點值具有“數字”的設定位數。 在float中,即23位(+ 1'隱藏'位),並且在double中它是52位(+1)。 然而,每位得到大約3位數(正好:log2(10),如果我們使用十進制數表示),所以23位數字給出大約7-8位數字,53位數字大約16-17位數字。 剩下的只是“噪音”,由轉換為十進制數字后數字的最后幾位引起。

要具有無限精度,我們必須將值存儲為分數,或者具有無限數量的位。 當然,我們可以有一些其他有限的精度,比如100位,但我相信你也會抱怨它,因為它會在“出錯”之前再有15個左右的數字。

浮點只有很高的精度(23位值得精確)。 如果你真的想看到“0.333333333333333333333333333333”輸出,你可以創建一個自定義的“分數”類,它分別存儲分子和分母。 然后,您可以完全准確地計算任何給定點的數字。

暫無
暫無

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

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