2015-11-03 68 views
5

我正在運行物理實驗的模擬,所以我需要非常高的浮點精度(超過16位數)。我使用Boost.Multiprecision,但無論如何,我無法獲得高於16位數的精度。我運行C++和Eclipse編譯器模擬,例如:使用boost lib更高精度的浮點數(高於16位數)

#include <boost/math/constants/constants.hpp> 
#include <boost/multiprecision/cpp_dec_float.hpp> 
#include <iostream> 
#include <limits> 

using boost::multiprecision::cpp_dec_float_50; 

void main() 
{ 
    cpp_dec_float_50 my_num= cpp_dec_float_50(0.123456789123456789123456789); 
    std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10); 
    std::cout << my_num << std::endl; 
} 

輸出是:

0.12345678912345678379658409085095627233386039733887 
       ^

但它應該是:

0.123456789123456789123456789 

正如你可以看到,16後數字不正確。爲什麼?

回答

11

你的問題就在這裏:

cpp_dec_float_50 my_num = cpp_dec_float_50(0.123456789123456789123456789); 
              ^// This number is a double! 

的編譯器不使用任意精度浮點文字,而是使用IEEE-754 雙打,具有有限的精度。在這種情況下,最接近double給你寫的數字是:

0.1234567891234567837965840908509562723338603973388671875 

而且將它打印到小數點第50確實給你所觀察的輸出。

你需要的是從字符串構建你的任意精度浮點數,而不是(demo):

#include <boost/math/constants/constants.hpp> 
#include <boost/multiprecision/cpp_dec_float.hpp> 
#include <iostream> 
#include <limits> 

using boost::multiprecision::cpp_dec_float_50; 

int main() { 
    cpp_dec_float_50 my_num = cpp_dec_float_50("0.123456789123456789123456789"); 
    std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10); 
    std::cout << my_num << std::endl; 
} 

輸出:

0.123456789123456789123456789 
2

問題是編譯時C++編譯器會將數字轉換爲雙精度(前一段也是learned)。你必須使用特殊的函數來處理更多的小數點。有關示例,請參閱SO上的Boost documentation或其他answers

也就是說,幾乎不可能有這樣高精度的實際需求。如果你失去了精度,你應該考慮其他浮點算法,而不是盲目地增加小數位數。