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?
Store the value in a higher-precision variable. E.g., instead of float step , use double step . In this case the value you've calculated won't be rounded once more, so precision will be higher.
The Difference Between Single and Double PrecisionFor single precision, 32 bits are used to represent the floating-point number. For double precision, 64 bits are used to represent the floating-point number.
In a 32-bit system, 23 digits after the decimal point can be stored. Precision defines how many bits will be occupied in memory to store the number. The more bits are made available, the more digits after the decimal point can be stored before rounding occurs.
Double precision numbers are accurate up to sixteen decimal places but after calculations have been done there may be some rounding errors to account for. In theory this should affect no more than the last significant digit but in practice it is safer to rely upon fewer decimal places.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With