6

物理実験のシミュレーションを実行しているので、非常に高い浮動小数点精度 (16 桁以上) が必要です。Boost.Multiprecision を使用していますが、何を試しても 16 桁を超える精度は得られません。たとえば、C++ と eclipse コンパイラを使用してシミュレーションを実行します。

#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 桁以降は正しくありません。なんで?

4

2 に答える 2

13

あなたの問題はここにあります:

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

コンパイラは、任意精度の浮動小数点リテラルを使用せず、代わりに有限精度の IEEE-754 doubleを使用します。この場合、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
于 2015-11-03T08:53:00.500 に答える
2

問題は、C++ コンパイラがコンパイル時に数値を double に変換することです (これも少し前に学びました)。より多くの小数点を処理するには、特別な関数を使用する必要があります。例については、 Boost のドキュメントまたはSO に関するその他の回答を参照してください。

とはいえ、そのような高精度が実際に必要になることはほとんどありません。精度が低下している場合は、やみくもに小数点以下の桁数を増やすのではなく、他の浮動小数点アルゴリズムを検討する必要があります。

于 2015-11-03T08:52:33.657 に答える