higher precision floating point using boost lib (h

2019-01-19 20:00发布

I am running a simulation of physical experiments, so I need really high floating point precision (more than 16 digits). I use Boost.Multiprecision, however I can't get a precision higher than 16 digits, no matter what I tried. I run the simulation with C++ and eclipse compiler, for example:

#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;
}

The output is:

0.12345678912345678379658409085095627233386039733887
                   ^

But it should be:

0.123456789123456789123456789

As you can see, after 16 digits it is incorrect. Why?

2条回答
该账号已被封号
2楼-- · 2019-01-19 20:30

Your issue is here:

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

The compiler does not use arbitrary-precision floating point literals, and instead uses IEEE-754 doubles, which have finite precision. In this case, the closest double to the number you have written is:

0.1234567891234567837965840908509562723338603973388671875

And printing it to the 50th decimal does indeed give the output you are observing.

What you want is to construct your arbitrary-precision float from a string instead (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;
}

Output:

0.123456789123456789123456789
查看更多
淡お忘
3楼-- · 2019-01-19 20:38

The problem is that the C++ compiler converts numbers to doubles when compiling (I also learned this a while ago). You have to use special functions to handle more decimal points. See the Boost documentation or other answers here on SO for examples.

That said, it is almost impossible that there would be any real need for such high precision. If you are loosing precision you should consider other floating point algorithms instead of blindly increasing the number of decimals.

查看更多
登录 后发表回答