2015-11-03 49 views
5

私は物理的なシミュレーションを行っていますので、浮動小数点精度(16桁以上)が必要です。 Boost.Multiprecisionを使用していますが、何を試しても16桁以上の精度は得られません。浮動小数点型の浮動小数点数を使用している浮動小数点数は、浮動小数点数の上位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; 
} 

出力は次のとおりです:私は、例えば、C++およびEclipseのコンパイラでシミュレーションを実行

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これはもう少し前です)。特殊な関数を使用して小数点以下を処理する必要があります。例については、Boost documentationまたは他のanswersをここに記載されています。

しかし、このような高い精度が本当に必要なのはほとんど不可能です。精度を失う場合は、小数点以下を盲目的に増加させる代わりに、他の浮動小数点アルゴリズムを考慮する必要があります。

関連する問題