2015-04-05 44 views
-3
... 
cout << setprecision(100) << pow((3+sqrt(5.0)),28) << endl; 
... 

輸出不能使C++程序使用足夠高的精度

135565048129406451712 

這是不夠精確,但。

$ bc <<< "scale = 100; (3+sqrt(5.0))^28" 

輸出

135565048129406369791.9994684648068789538123313610677119237534230237579838585720347675878761558402979025019238688523799354 

這就是我想要的。我正在設置cout精度,因此它必須是sqrt,pow+正在失去精度?

+0

'bc'具有無限精度,C++中的'double'沒有。 – Barry 2015-04-05 16:28:05

+0

您需要使用一個固定的十進制精度數字來代表這一點。 'double'不支持這個。 – 2015-04-05 16:28:14

+2

標準雙打通常只有64位精度,遠遠低於100位有效數字。如果你需要的話,你需要使用任意精度的數學庫。 – 2015-04-05 16:28:50

回答

2

cout的設置精度對底層計算在C++中的完成方式沒有任何影響。典型地具有大約8個數字的精確度,doubles大約16個;你的C++輸出只有前15位與bc輸出匹配。

如果你想要更高的精度,那麼你將不得不使用另一種方法,如任意精度的數值庫。這就是bc程序如何實現任意精度的數學運算。

例如,使用:

https://gmplib.org

#include <gmp.h> 
#include <gmpxx.h> 

#include <iostream> 
#include <iomanip> 

int main() { 
    mpf_set_default_prec(402); 

    mpf_class a = 3_mpf + sqrt(5_mpf); 
    mpf_class output; 
    mpf_pow_ui(output.get_mpf_t(), a.get_mpf_t(), 28); 

    std::cout << std::setprecision(121); 
    std::cout << output << '\n'; 
} 

此打印:

135565048129406369791.9994684648068789538123313610677119237534230237579838585720347675878761558402979528909982661363879709

有趣的是,這與bc <<< "scale = 100; (3+sqrt(5.0))^28"的輸出不同,但如果您將bc的比例設置得更高,則會看到gmp的輸出是正確的。

看起來像bc願意打印出它的許多數字,即使生成這些數字的表達式的操作數沒有足夠的精度來使它們正確。相比之下,GMP似乎根據給定輸入精度的準確度來設置結果精度。

+0

更正,除了錯誤的斷言,任何給定的浮點類型的對象根據C++的抽象都有一些預定的精度。 – 2015-04-05 16:37:34