I have already read most of the SO questions related to "rounding to n digits". I believe that this question is separate because it is more related to the rounding of arbitrary-length floats.
0.56714329040978387299996866221035554975381578718651250813513107922304579308668456669321944696175229455773495728285284421635951688
The number above is an example of the types of numbers I am working with.
I understand how to round a number in C++, it is fairly simple. However, I do not understand how I can round arbitrarily-long numbers to n digits.
For example, I may have a number that is 192 digits long that I need to round to 84 digits, or a number that is 1831 digits that I need to round to 293 digits. How can this be done using one function (or similar)?
Pseudocode for clarity, but I am actually using Boost multi-precision cpp_dec_float for arbitrary-precision floats instead of standard floats:
float round(float num, int digits){
//returns num rounded to n digits
}
Another problem that I have come across is when trying to round very long floats to a small number of digits.
For example, if I have a number that is 1000 digits long, and I want to round it to n digits, I have to do something like floor(num * 10^1000)/10^1000)
. This doesn't work because 10^1000 is extremely large. A solution to this would be doing the multiplication and division multiple times with smaller exponents.
[Edited - better solution]
Doing the rounding can go based on:
round(x, precision_unit)=trunc(x/precision_unit+0.5)*precision_unit;
Something like:
using namespace boost::multiprecision;
const uint lower_prec_digits=28;
typedef number<cpp_dec_float<100>> higher_prec;
typedef number<cpp_dec_float<lower_prec_digits>> lower_prec;
const higher_prec eps_div=
std::numeric_limits<
number<cpp_dec_float<lower_prec_digits+1>>
>::epsilon()
;
higher_prec pi(
"3.1415926535"
"8979323846"
"2643383279"
"5028841971"
"6939937510"
"5820974944"
"5923078164"
"0628620899"
"8628034825"
"3421170679"
);
lower_prec round_pie=lower_prec(trunc(pi/eps_div+0.5)*eps_div);
std::cout.precision(100);
std::cout << round_pie << std::endl << pi << std::endl;
Result:
3.1415926535897932384626433833
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068